<!DOCTYPE html>


<html theme="dark" showBanner="true" hasBanner="false" > 
<link href="/blog/fontawesome/css/fontawesome.css" rel="stylesheet">
<link href="/blog/fontawesome/css/brands.css" rel="stylesheet">
<link href="/blog/fontawesome/css/solid.css" rel="stylesheet">
<script src="/blog/js/color.global.min.js" ></script>
<script src="/blog/js/load-settings.js" ></script>
<head>
  <meta charset="utf-8">
  
  
  

  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <link rel="preload" href="/blog/css/fonts/Roboto-Regular.ttf" as="font" type="font/ttf" crossorigin="anonymous">
  <link rel="preload" href="/blog/css/fonts/Roboto-Bold.ttf" as="font" type="font/ttf" crossorigin="anonymous">

  <meta name="description" content="一、LCD硬件原理1.1 CRT介绍CRT是阴极射线管（Cathode Ray Tube）的缩写，它是一种使用电子束在荧光屏上创建图像的显示设备。CRT显示器在过去很长一段时间内是主流的显示技术，现已被液晶显示屏或其他新兴技术所替代。 在CRT显示器中，扫描电子束从左到右、从上到下移动，照亮屏幕上的荧光点，从而创建图像。电子束每秒多次扫描整个屏幕，产生闪烁效果，需要与正在显示的内容同步。 随着LC">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://zyly2033.gitee.io/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20crtc/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="一、LCD硬件原理1.1 CRT介绍CRT是阴极射线管（Cathode Ray Tube）的缩写，它是一种使用电子束在荧光屏上创建图像的显示设备。CRT显示器在过去很长一段时间内是主流的显示技术，现已被液晶显示屏或其他新兴技术所替代。 在CRT显示器中，扫描电子束从左到右、从上到下移动，照亮屏幕上的荧光点，从而创建图像。电子束每秒多次扫描整个屏幕，产生闪烁效果，需要与正在显示的内容同步。 随着LC">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://gitee.com/zyly2033/blog-pic/raw/master/202309022237381.gif">
<meta property="og:image" content="https://gitee.com/zyly2033/blog-pic/raw/master/202309022243381.png">
<meta property="og:image" content="https://gitee.com/zyly2033/blog-pic/raw/master/202309022308840.png">
<meta property="og:image" content="https://gitee.com/zyly2033/blog-pic/raw/master/202309022145790.png">
<meta property="article:published_time" content="2023-09-11T12:23:16.185Z">
<meta property="article:modified_time" content="2023-09-02T15:44:19.236Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/zyly2033/blog-pic/raw/master/202309022237381.gif">
  
    <link rel="alternate" href="/blog/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" media="(prefers-color-scheme: light)" href="/blog/images/favicon-light-32.png" sizes="32x32">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/blog/images/favicon-light-128.png" sizes="128x128">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/blog/images/favicon-light-180.png" sizes="180x180">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/blog/images/favicon-light-192.png" sizes="192x192">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/blog/images/favicon-dark-32.png" sizes="32x32">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/blog/images/favicon-dark-128.png" sizes="128x128">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/blog/images/favicon-dark-180.png" sizes="180x180">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/blog/images/favicon-dark-192.png" sizes="192x192">
  
  
<link rel="stylesheet" href="/blog/css/style.css">

<meta name="generator" content="Hexo 6.3.0"></head>

<body>
  
   
  <div id="main-grid" class="shadow   ">
    <div id="nav" class=""  >
      <navbar id="navbar">
  <nav id="title-nav">
    <a href="/blog/">
      <div id="vivia-logo">
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
      </div>
      <div>Hexo </div>
    </a>
  </nav>
  <nav id="main-nav">
    
      <a class="main-nav-link" href="/blog/">Home</a>
    
      <a class="main-nav-link" href="/blog/archives">Archives</a>
    
      <a class="main-nav-link" href="/blog/about">About</a>
    
  </nav>
  <nav id="sub-nav">
    <a id="theme-btn" class="nav-icon">
      <span class="light-mode-icon"><svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M438.5-829.913v-48q0-17.452 11.963-29.476 11.964-12.024 29.326-12.024 17.363 0 29.537 12.024t12.174 29.476v48q0 17.452-11.963 29.476-11.964 12.024-29.326 12.024-17.363 0-29.537-12.024T438.5-829.913Zm0 747.826v-48q0-17.452 11.963-29.476 11.964-12.024 29.326-12.024 17.363 0 29.537 12.024t12.174 29.476v48q0 17.452-11.963 29.476-11.964 12.024-29.326 12.024-17.363 0-29.537-12.024T438.5-82.087ZM877.913-438.5h-48q-17.452 0-29.476-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537t29.476-12.174h48q17.452 0 29.476 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T877.913-438.5Zm-747.826 0h-48q-17.452 0-29.476-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537T82.087-521.5h48q17.452 0 29.476 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T130.087-438.5Zm660.174-290.87-34.239 32q-12.913 12.674-29.565 12.174-16.653-.5-29.327-13.174-12.674-12.673-12.554-28.826.12-16.152 12.794-28.826l33-35q12.913-12.674 30.454-12.674t30.163 12.847q12.709 12.846 12.328 30.826-.38 17.98-13.054 30.653ZM262.63-203.978l-32 34q-12.913 12.674-30.454 12.674t-30.163-12.847q-12.709-12.846-12.328-30.826.38-17.98 13.054-30.653l33.239-31q12.913-12.674 29.565-12.174 16.653.5 29.327 13.174 12.674 12.673 12.554 28.826-.12 16.152-12.794 28.826Zm466.74 33.239-32-33.239q-12.674-12.913-12.174-29.565.5-16.653 13.174-29.327 12.673-12.674 28.826-13.054 16.152-.38 28.826 12.294l35 33q12.674 12.913 12.674 30.454t-12.847 30.163q-12.846 12.709-30.826 12.328-17.98-.38-30.653-13.054ZM203.978-697.37l-34-33q-12.674-12.913-13.174-29.945-.5-17.033 12.174-29.707t31.326-13.293q18.653-.62 31.326 13.054l32 34.239q11.674 12.913 11.174 29.565-.5 16.653-13.174 29.327-12.673 12.674-28.826 12.554-16.152-.12-28.826-12.794ZM480-240q-100 0-170-70t-70-170q0-100 70-170t170-70q100 0 170 70t70 170q0 100-70 170t-170 70Zm-.247-82q65.703 0 111.475-46.272Q637-414.544 637-480.247t-45.525-111.228Q545.95-637 480.247-637t-111.475 45.525Q323-545.95 323-480.247t45.525 111.975Q414.05-322 479.753-322ZM481-481Z"/></svg></span>
      <span class="dark-mode-icon"><svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M480.239-116.413q-152.63 0-258.228-105.478Q116.413-327.37 116.413-480q0-130.935 77.739-227.435t206.304-125.043q43.022-9.631 63.87 10.869t3.478 62.805q-8.891 22.043-14.315 44.463-5.424 22.42-5.424 46.689 0 91.694 64.326 155.879 64.325 64.186 156.218 64.186 24.369 0 46.978-4.946 22.609-4.945 44.413-14.076 42.826-17.369 62.967 1.142 20.142 18.511 10.511 61.054Q807.174-280 712.63-198.206q-94.543 81.793-232.391 81.793Zm0-95q79.783 0 143.337-40.217 63.554-40.218 95.793-108.283-15.608 4.044-31.097 5.326-15.49 1.283-31.859.805-123.706-4.066-210.777-90.539-87.071-86.473-91.614-212.092-.24-16.369.923-31.978 1.164-15.609 5.446-30.978-67.826 32.478-108.282 96.152Q211.652-559.543 211.652-480q0 111.929 78.329 190.258 78.329 78.329 190.258 78.329ZM466.13-465.891Z"/></svg></span>
    </a>
    
      <a id="nav-rss-link" class="nav-icon mobile-hide" href="/blog/atom.xml" title="RSS Feed">
        <svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M198-120q-25.846 0-44.23-18.384-18.384-18.385-18.384-44.23 0-25.846 18.384-44.23 18.384-18.385 44.23-18.385 25.846 0 44.23 18.385 18.384 18.384 18.384 44.23 0 25.845-18.384 44.23Q223.846-120 198-120Zm538.385 0q-18.846 0-32.923-13.769-14.076-13.769-15.922-33.23-8.692-100.616-51.077-188.654-42.385-88.039-109.885-155.539-67.5-67.501-155.539-109.885Q283-663.462 182.385-672.154q-19.461-1.846-33.23-16.23-13.769-14.385-13.769-33.846t14.076-32.922q14.077-13.461 32.923-12.23 120.076 8.692 226.038 58.768 105.961 50.077 185.73 129.846 79.769 79.769 129.846 185.731 50.077 105.961 58.769 226.038 1.231 18.846-12.538 32.922Q756.461-120 736.385-120Zm-252 0q-18.231 0-32.423-13.461t-18.653-33.538Q418.155-264.23 348.886-333.5q-69.27-69.27-166.501-84.423-20.077-4.462-33.538-18.961-13.461-14.5-13.461-33.346 0-19.076 13.884-33.23 13.884-14.153 33.115-10.922 136.769 15.384 234.384 112.999 97.615 97.615 112.999 234.384 3.231 19.23-10.538 33.115Q505.461-120 484.385-120Z"/></svg>
      </a>
    
    <div id="nav-menu-btn" class="nav-icon">
      <svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M177.37-252.282q-17.453 0-29.477-11.964-12.024-11.963-12.024-29.326t12.024-29.537q12.024-12.174 29.477-12.174h605.26q17.453 0 29.477 11.964 12.024 11.963 12.024 29.326t-12.024 29.537q-12.024 12.174-29.477 12.174H177.37Zm0-186.218q-17.453 0-29.477-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537T177.37-521.5h605.26q17.453 0 29.477 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T782.63-438.5H177.37Zm0-186.217q-17.453 0-29.477-11.964-12.024-11.963-12.024-29.326t12.024-29.537q12.024-12.174 29.477-12.174h605.26q17.453 0 29.477 11.964 12.024 11.963 12.024 29.326t-12.024 29.537q-12.024 12.174-29.477 12.174H177.37Z"/></svg>
    </div>
  </nav>
</navbar>
<div id="nav-dropdown" class="hidden">
  <div id="dropdown-link-list">
    
      <a class="nav-dropdown-link" href="/blog/">Home</a>
    
      <a class="nav-dropdown-link" href="/blog/archives">Archives</a>
    
      <a class="nav-dropdown-link" href="/blog/about">About</a>
    
    
      <a class="nav-dropdown-link" href="/blog/atom.xml" title="RSS Feed">RSS</a>
     
    </div>
</div>
<script>
  let dropdownBtn = document.getElementById("nav-menu-btn");
  let dropdownEle = document.getElementById("nav-dropdown");
  dropdownBtn.onclick = function() {
    dropdownEle.classList.toggle("hidden");
  }
</script>
    </div>
    <div id="sidebar-wrapper">
      <sidebar id="sidebar">
  
    <div class="widget-wrap">
  <div class="info-card">
    <div class="avatar">
      
      <div class="img-dim"></div>
    </div>
    <div class="info">
      <div class="username">Your Name </div>
      <div class="dot"></div>
      <div class="subtitle">This is the subtitle </div>
      <div class="link-list">
        
          <a class="link-btn" target="_blank" rel="noopener" href="https://twitter.com" title="Twitter"><i class="fa-brands fa-twitter"></i></a>
        
          <a class="link-btn" target="_blank" rel="noopener" href="https://store.steampowered.com" title="Steam"><i class="fa-brands fa-steam"></i></a>
        
          <a class="link-btn" target="_blank" rel="noopener" href="https://github.com" title="GitHub"><i class="fa-brands fa-github"></i></a>
         
      </div>  
    </div>
  </div>
</div>

  
  <div class="sticky">
    
      



    
      

    
      
  <div class="widget-wrap">
    <div class="widget">
      <h3 class="widget-title">Archives</h3>
      
      
        <a class="archive-link" href="/blog/archives/2023/09 ">
          September 2023 
          <div class="archive-count">8 </div>
        </a>
      
    </div>
  </div>


    
      
  <div class="widget-wrap">
    <div class="widget">
      <h3 class="widget-title">Recent Posts</h3>
      <ul>
        
          <a class="recent-link" href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%E9%A9%B1%E5%8A%A8%E7%A8%8B%E5%BA%8F/" title="" >
            <div class="recent-link-text">
              (no title)
            </div>
          </a>
        
          <a class="recent-link" href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%E5%AD%90%E7%B3%BB%E7%BB%9F/" title="" >
            <div class="recent-link-text">
              (no title)
            </div>
          </a>
        
          <a class="recent-link" href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20plane/" title="" >
            <div class="recent-link-text">
              (no title)
            </div>
          </a>
        
          <a class="recent-link" href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20framebuffer/" title="" >
            <div class="recent-link-text">
              (no title)
            </div>
          </a>
        
          <a class="recent-link" href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20crtc/" title="" >
            <div class="recent-link-text">
              (no title)
            </div>
          </a>
        
      </ul>
    </div>
  </div>

    
  </div>
</sidebar>
    </div>
    <div id="content-body">
       

<article id="post-rk3399/Rockchip RK3399 - DRM crtc" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  
    
   
  <div class="article-inner">
    <div class="article-main">
      <header class="article-header">
        
<div class="main-title-bar">
  <div class="main-title-dot"></div>
  
    
      <h1 class="p-name article-title" itemprop="headline name">
        Untitled
      </h1>
    
  
</div>

        <div class='meta-info-bar'>
          <div class="meta-info">
  <time class="dt-published" datetime="2023-09-11T12:23:16.185Z" itemprop="datePublished">2023-09-11</time>
</div>
          <div class="need-seperator meta-info">
            <div class="meta-cate-flex">
  
    Uncategorized 
   
</div>
  
          </div>
          <div class="wordcount need-seperator meta-info">
            10k words 
          </div>
        </div>
        
      </header>
      <div class="e-content article-entry" itemprop="articleBody">
        
          <h3 id="一、LCD硬件原理"><a href="#一、LCD硬件原理" class="headerlink" title="一、LCD硬件原理"></a>一、LCD硬件原理</h3><h4 id="1-1-CRT介绍"><a href="#1-1-CRT介绍" class="headerlink" title="1.1 CRT介绍"></a>1.1 CRT介绍</h4><p>CRT是阴极射线管（Cathode Ray Tube）的缩写，它是一种使用电子束在荧光屏上创建图像的显示设备。CRT显示器在过去很长一段时间内是主流的显示技术，现已被液晶显示屏或其他新兴技术所替代。</p>
<p>在CRT显示器中，扫描电子束从左到右、从上到下移动，照亮屏幕上的荧光点，从而创建图像。电子束每秒多次扫描整个屏幕，产生闪烁效果，需要与正在显示的内容同步。</p>
<p>随着LCD、LED和OLED等新型显示技术的出现，底层原理已经发生了变化。这些显示器不再使用扫描电子束，而是使用可以单独控制发光或阻挡光的像素矩阵。这使得图像更加清晰，刷新率更快，能源效率也得到了提高。</p>
<p>然而，刷新显示的基本概念并没有发生很大变化。显示内容仍然通过向每个像素发送信号来控制其亮度和颜色来进行更新。这些信号由显示控制器根据输入视频信号生成，并且它们确定屏幕上显示的内容。</p>
<h4 id="1-2-LCD示意图"><a href="#1-2-LCD示意图" class="headerlink" title="1.2 LCD示意图"></a>1.2 LCD示意图</h4><p>下图是LCD示意图，里面的每个点就是一个像素点。它里面有一个电子枪，一边移动，一边发出各种颜色的光。用动态图表示如下：</p>
<p><img src="https://gitee.com/zyly2033/blog-pic/raw/master/202309022237381.gif" alt="img"></p>
<p>电子枪是如何移动的？</p>
<ul>
<li>有一条Pixel Clock时钟线与LCD相连，每发出一次Pixel Clock，电子枪就移动一个像素。</li>
</ul>
<p>颜色如何确定？</p>
<ul>
<li>由连接LCD的三组线RGB三原色混合而成：R(Red)、G(Green)、B(Blue)确定。</li>
</ul>
<p>电子枪如何得知应跳到下一行？</p>
<ul>
<li>有一条HSYNC信号线与LCD相连，每发出一次脉冲(高低电平)，电子枪就跳到下一行，该信号叫做行同步信号。</li>
</ul>
<p>电子枪如何得知应跳到原点？</p>
<ul>
<li>有一条VSYNC信号线与LCD相连，每发出一次脉冲(高低电平)，电子枪就跳到原点，该信号叫做帧同步信号。</li>
</ul>
<p>RGB线上的数据从何而来？</p>
<ul>
<li>内存里面划分一块显存(FrameBuffer)，里面存放了要显示的数据，LCD控制器从里面将数据读出来，通过RGB三组线传给电子枪，电子枪再依次打到显示屏上。</li>
</ul>
<p>因此要想在显示设备上显示图像，至少需要3个信号：</p>
<ul>
<li>Pixel Clock：时钟信号，在每个时钟周期更新屏幕上一个像素；</li>
<li>HSYNC：水平同步信号，引脚每发出一个脉冲，表示一行的数据开始发送；</li>
<li>VSYNC：垂直同步信号，引脚每发出一个脉冲，表示一帧的数据开始发送。</li>
</ul>
<h4 id="1-3-时序参数"><a href="#1-3-时序参数" class="headerlink" title="1.3 时序参数"></a>1.3 时序参数</h4><p><img src="https://gitee.com/zyly2033/blog-pic/raw/master/202309022243381.png"></p>
<p><img src="https://gitee.com/zyly2033/blog-pic/raw/master/202309022308840.png"></p>
<p>在上图中我们发现除了Pixel Clock、HSYNC、VSYNC信号外，还包含了大量的时序参数，这里我们一一介绍：</p>
<ul>
<li>HBPD（hback porch）：行同步信号的后肩，单位为1个Pixel Clock时钟周期；</li>
<li>HFPD（hfront porch）：行同步信号的前肩，单位为1个Pixel Clock时钟周期；</li>
<li>HSPW（hsync pulse）：行同步信号的脉宽，单位为1个Pixel Clock时钟周期；</li>
<li>HOZVAL（hdisplay）：LCD的水平宽度；</li>
<li>VBPD（vback porch）：帧同步信号的后肩，单位为1个HSYNC时钟周期；</li>
<li>VFPD（vfront porch）：帧同步信号的前肩，单位为1个HSYNC时钟周期；</li>
<li>VSPW（vsync pulse）：帧同步信号的脉宽，单位为1个HSYNC时钟周期；</li>
<li>LINEVAL （vdisplay）：LCD的垂直宽度；</li>
</ul>
<p>如果这部分内容看不到，可以参考我之前写的这篇文章：<a target="_blank" rel="noopener" href="https://www.cnblogs.com/zyly/p/15407570.html">Mini2440裸机开发之LCD基础</a>。</p>
<h3 id="二、CRTC核心数据结构"><a href="#二、CRTC核心数据结构" class="headerlink" title="二、CRTC核心数据结构"></a>二、CRTC核心数据结构</h3><p><img src="https://gitee.com/zyly2033/blog-pic/raw/master/202309022145790.png"></p>
<p>在DRM框架中，CRTC从Framebuffer中读取待显示的图像，并按照响应的格式输出给encoder，其主要承担的作用为：</p>
<ul>
<li>配置适合显示的显示模式、分辨率、刷新率等参数，并输出相应的时序；</li>
<li>扫描Framebuffer发送到一个或多个显示器；</li>
<li>更新Framebuffer；</li>
</ul>
<p>概括下就是，对显示器进行扫描，产生时序信号的模块、负责帧切换、电源控制、色彩调整等等。</p>
<h4 id="2-1-struct-drm-crtc"><a href="#2-1-struct-drm-crtc" class="headerlink" title="2.1 struct drm_crtc"></a>2.1 struct drm_crtc</h4><p>linux内核使用struct drm_crtc来表示一个CRT控制器，包括显示模式、分辨率、刷新率等参数。定义在include&#x2F;drm&#x2F;drm_crtc.h；</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * struct drm_crtc - central CRTC control structure</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Each CRTC may have one or more connectors associated with it.  This structure</span></span><br><span class="line"><span class="comment"> * allows the CRTC to be controlled.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc</span> &#123;</span></span><br><span class="line">        <span class="comment">/** @dev: parent DRM device */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_device</span> *<span class="title">dev</span>;</span></span><br><span class="line">        <span class="comment">/** @port: OF node used by drm_of_find_possible_crtcs(). */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">device_node</span> *<span class="title">port</span>;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @head:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * List of all CRTCs on @dev, linked from &amp;drm_mode_config.crtc_list.</span></span><br><span class="line"><span class="comment">         * Invariant over the lifetime of @dev and therefore does not need</span></span><br><span class="line"><span class="comment">         * locking.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">list_head</span> <span class="title">head</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/** @name: human readable name, can be overwritten by the driver */</span></span><br><span class="line">        <span class="type">char</span> *name;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mutex:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This provides a read lock for the overall CRTC state (mode, dpms</span></span><br><span class="line"><span class="comment">         * state, ...) and a write lock for everything which can be update</span></span><br><span class="line"><span class="comment">         * without a full modeset (fb, cursor data, CRTC properties ...). A full</span></span><br><span class="line"><span class="comment">         * modeset also need to grab &amp;drm_mode_config.connection_mutex.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For atomic drivers specifically this protects @state.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_modeset_lock</span> <span class="title">mutex</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/** @base: base KMS object for ID tracking etc. */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_mode_object</span> <span class="title">base</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @primary:</span></span><br><span class="line"><span class="comment">         * Primary plane for this CRTC. Note that this is only</span></span><br><span class="line"><span class="comment">         * relevant for legacy IOCTL, it specifies the plane implicitly used by</span></span><br><span class="line"><span class="comment">         * the SETCRTC and PAGE_FLIP IOCTLs. It does not have any significance</span></span><br><span class="line"><span class="comment">         * beyond that.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_plane</span> *<span class="title">primary</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor:</span></span><br><span class="line"><span class="comment">         * Cursor plane for this CRTC. Note that this is only relevant for</span></span><br><span class="line"><span class="comment">         * legacy IOCTL, it specifies the plane implicitly used by the SETCURSOR</span></span><br><span class="line"><span class="comment">         * and SETCURSOR2 IOCTLs. It does not have any significance</span></span><br><span class="line"><span class="comment">         * beyond that.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_plane</span> *<span class="title">cursor</span>;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @index: Position inside the mode_config.list, can be used as an array</span></span><br><span class="line"><span class="comment">         * index. It is invariant over the lifetime of the CRTC.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">unsigned</span> index;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor_x: Current x position of the cursor, used for universal</span></span><br><span class="line"><span class="comment">         * cursor planes because the SETCURSOR IOCTL only can update the</span></span><br><span class="line"><span class="comment">         * framebuffer without supplying the coordinates. Drivers should not use</span></span><br><span class="line"><span class="comment">         * this directly, atomic drivers should look at &amp;drm_plane_state.crtc_x</span></span><br><span class="line"><span class="comment">         * of the cursor plane instead.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> cursor_x;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor_y: Current y position of the cursor, used for universal</span></span><br><span class="line"><span class="comment">         * cursor planes because the SETCURSOR IOCTL only can update the</span></span><br><span class="line"><span class="comment">         * framebuffer without supplying the coordinates. Drivers should not use</span></span><br><span class="line"><span class="comment">         * this directly, atomic drivers should look at &amp;drm_plane_state.crtc_y</span></span><br><span class="line"><span class="comment">         * of the cursor plane instead.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> cursor_y;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @enabled:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Is this CRTC enabled? Should only be used by legacy drivers, atomic</span></span><br><span class="line"><span class="comment">         * drivers should instead consult &amp;drm_crtc_state.enable and</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.active. Atomic drivers can update this by calling</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_update_legacy_modeset_state().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> enabled;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Current mode timings. Should only be used by legacy drivers, atomic</span></span><br><span class="line"><span class="comment">         * drivers should instead consult &amp;drm_crtc_state.mode. Atomic drivers</span></span><br><span class="line"><span class="comment">         * can update this by calling</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_update_legacy_modeset_state().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_display_mode</span> <span class="title">mode</span>;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @hwmode:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Programmed mode in hw, after adjustments for encoders, crtc, panel</span></span><br><span class="line"><span class="comment">         * scaling etc. Should only be used by legacy drivers, for high</span></span><br><span class="line"><span class="comment">         * precision vblank timestamps in</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_helper_get_vblank_timestamp().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that atomic drivers should not use this, but instead use</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.adjusted_mode. And for high-precision timestamps</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_helper_get_vblank_timestamp() used</span></span><br><span class="line"><span class="comment">         * &amp;drm_vblank_crtc.hwmode,</span></span><br><span class="line"><span class="comment">         * which is filled out by calling drm_calc_timestamping_constants().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_display_mode</span> <span class="title">hwmode</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @x:</span></span><br><span class="line"><span class="comment">         * x position on screen. Should only be used by legacy drivers, atomic</span></span><br><span class="line"><span class="comment">         * drivers should look at &amp;drm_plane_state.crtc_x of the primary plane</span></span><br><span class="line"><span class="comment">         * instead. Updated by calling</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_update_legacy_modeset_state().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> x;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @y:</span></span><br><span class="line"><span class="comment">         * y position on screen. Should only be used by legacy drivers, atomic</span></span><br><span class="line"><span class="comment">         * drivers should look at &amp;drm_plane_state.crtc_y of the primary plane</span></span><br><span class="line"><span class="comment">         * instead. Updated by calling</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_update_legacy_modeset_state().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> y;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/** @funcs: CRTC control functions */</span></span><br><span class="line">        <span class="type">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_funcs</span> *<span class="title">funcs</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @gamma_size: Size of legacy gamma ramp reported to userspace. Set up</span></span><br><span class="line"><span class="comment">         * by calling drm_mode_crtc_set_gamma_size().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that atomic drivers need to instead use</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">uint32_t</span> gamma_size;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @gamma_store: Gamma ramp values used by the legacy SETGAMMA and</span></span><br><span class="line"><span class="comment">         * GETGAMMA IOCTls. Set up by calling drm_mode_crtc_set_gamma_size().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that atomic drivers need to instead use</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">uint16_t</span> *gamma_store;</span><br><span class="line">        <span class="comment">/** @helper_private: mid-layer private data */</span></span><br><span class="line">        <span class="type">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_helper_funcs</span> *<span class="title">helper_private</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/** @properties: property tracking for this CRTC */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_object_properties</span> <span class="title">properties</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @scaling_filter_property: property to apply a particular filter while</span></span><br><span class="line"><span class="comment">         * scaling.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_property</span> *<span class="title">scaling_filter_property</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @state:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Current atomic state for this CRTC.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is protected by @mutex. Note that nonblocking atomic commits</span></span><br><span class="line"><span class="comment">         * access the current CRTC state without taking locks. Either by going</span></span><br><span class="line"><span class="comment">         * through the &amp;struct drm_atomic_state pointers, see</span></span><br><span class="line"><span class="comment">         * for_each_oldnew_crtc_in_state(), for_each_old_crtc_in_state() and</span></span><br><span class="line"><span class="comment">         * for_each_new_crtc_in_state(). Or through careful ordering of atomic</span></span><br><span class="line"><span class="comment">         * commit operations as implemented in the atomic helpers, see</span></span><br><span class="line"><span class="comment">         * &amp;struct drm_crtc_commit.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_state</span> *<span class="title">state</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @commit_list:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * List of &amp;drm_crtc_commit structures tracking pending commits.</span></span><br><span class="line"><span class="comment">         * Protected by @commit_lock. This list holds its own full reference,</span></span><br><span class="line"><span class="comment">         * as does the ongoing commit.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * &quot;Note that the commit for a state change is also tracked in</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.commit. For accessing the immediately preceding</span></span><br><span class="line"><span class="comment">         * commit in an atomic update it is recommended to just use that</span></span><br><span class="line"><span class="comment">         * pointer in the old CRTC state, since accessing that doesn&#x27;t need</span></span><br><span class="line"><span class="comment">         * any locking or list-walking. @commit_list should only be used to</span></span><br><span class="line"><span class="comment">         * stall for framebuffer cleanup that&#x27;s signalled through</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_commit.cleanup_done.&quot;</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">list_head</span> <span class="title">commit_list</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @commit_lock:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Spinlock to protect @commit_list.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">spinlock_t</span> commit_lock;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @debugfs_entry:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Debugfs directory for this CRTC.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">dentry</span> *<span class="title">debugfs_entry</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @crc:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Configuration settings of CRC capture.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_crc</span> <span class="title">crc</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @fence_context:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * timeline context used for fence operations.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">unsigned</span> <span class="type">int</span> fence_context;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @fence_lock:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * spinlock to protect the fences in the fence_context.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">spinlock_t</span> fence_lock;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @fence_seqno:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Seqno variable used as monotonic counter for the fences</span></span><br><span class="line"><span class="comment">         * created on the CRTC&#x27;s timeline.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">unsigned</span> <span class="type">long</span> fence_seqno;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @timeline_name:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * The name of the CRTC&#x27;s fence timeline.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">char</span> timeline_name[<span class="number">32</span>];</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @self_refresh_data: Holds the state for the self refresh helpers</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Initialized via drm_self_refresh_helper_init().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_self_refresh_data</span> *<span class="title">self_refresh_data</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>该结构体包含以下成员变量：</p>
<ul>
<li>dev：该CRTC所属的DRM设备；</li>
<li>port：设备节点，被drm_of_find_possible_crtcs()使用；</li>
<li>head：链表节点，用于将当前节点添加到&amp;drm_mode_config.crtc_list链表；</li>
<li>name：名称，可以被驱动程序覆盖；</li>
<li>mutex：用于保护CRTC状态的互斥锁；</li>
<li>base： struct drm_mode_object；</li>
<li>primary：与该CRTC相关的primary plane；</li>
<li>cursor：与该CRTC相关的cursor plane；</li>
<li>index：在mode_config.list中的位置，可以用作数组索引；</li>
<li>cursor_x：光标的x坐标；</li>
<li>cursor_y：光标的y坐标；</li>
<li>enabled：指示该CRTC是否已启用；</li>
<li>mode：当前模式时序信息；</li>
<li>hwmode：硬件中编程的模式；</li>
<li>x：在屏幕上的x坐标；</li>
<li>y：在屏幕上的y坐标；</li>
<li>funcs：CRTC控制函数；</li>
<li>gamma_size：报告给用户空间的legacy gamma ramp大小；</li>
<li>gamma_store：legacy gamma values数据存储区域；</li>
<li>helper_private：中间层私有数据；</li>
<li>properties：跟踪该CRTC的属性；</li>
<li>scaling_filter_property：应用于缩放时的特定滤镜的属性；</li>
<li>state：当前CRTC的原子状态；</li>
<li>commit_list：跟踪挂起提交的列表；</li>
<li>commit_lock：保护commit_list的自旋锁；</li>
<li>debugfs_entry：用于调试的目录条目；</li>
<li>crc：CRC捕获的配置设置；</li>
<li>fence_context：用于围栏操作的时间线上下文；</li>
<li>fence_lock：保护时间线上的围栏的自旋锁；</li>
<li>fence_seqno：用作CRTC时间线上创建的围栏的单调计数器；</li>
<li>timeline_name：CRTC时间线的名称；</li>
<li>self_refresh_data：保存自刷新辅助程序状态的数据；</li>
</ul>
<h5 id="2-1-1-struct-drm-display-mode"><a href="#2-1-1-struct-drm-display-mode" class="headerlink" title="2.1.1 struct drm_display_mode"></a>2.1.1 struct drm_display_mode</h5><p>struct drm_display_mode用于表示显示模式，包含了显示的何种时序参数。定义在include&#x2F;drm&#x2F;drm_modes.h；</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * struct drm_display_mode - DRM kernel-internal display mode structure</span></span><br><span class="line"><span class="comment"> * @hdisplay: horizontal display size</span></span><br><span class="line"><span class="comment"> * @hsync_start: horizontal sync start</span></span><br><span class="line"><span class="comment"> * @hsync_end: horizontal sync end</span></span><br><span class="line"><span class="comment"> * @htotal: horizontal total size</span></span><br><span class="line"><span class="comment"> * @hskew: horizontal skew?!</span></span><br><span class="line"><span class="comment"> * @vdisplay: vertical display size</span></span><br><span class="line"><span class="comment"> * @vsync_start: vertical sync start</span></span><br><span class="line"><span class="comment"> * @vsync_end: vertical sync end</span></span><br><span class="line"><span class="comment"> * @vtotal: vertical total size</span></span><br><span class="line"><span class="comment"> * @vscan: vertical scan?!</span></span><br><span class="line"><span class="comment"> * @crtc_hdisplay: hardware mode horizontal display size</span></span><br><span class="line"><span class="comment"> * @crtc_hblank_start: hardware mode horizontal blank start</span></span><br><span class="line"><span class="comment"> * @crtc_hblank_end: hardware mode horizontal blank end</span></span><br><span class="line"><span class="comment"> * @crtc_hsync_start: hardware mode horizontal sync start</span></span><br><span class="line"><span class="comment"> * @crtc_hsync_end: hardware mode horizontal sync end</span></span><br><span class="line"><span class="comment"> * @crtc_htotal: hardware mode horizontal total size</span></span><br><span class="line"><span class="comment"> * @crtc_hskew: hardware mode horizontal skew?!</span></span><br><span class="line"><span class="comment"> * @crtc_vdisplay: hardware mode vertical display size</span></span><br><span class="line"><span class="comment"> * @crtc_vblank_start: hardware mode vertical blank start</span></span><br><span class="line"><span class="comment"> * @crtc_vblank_end: hardware mode vertical blank end</span></span><br><span class="line"><span class="comment"> * @crtc_vsync_start: hardware mode vertical sync start</span></span><br><span class="line"><span class="comment"> * @crtc_vsync_end: hardware mode vertical sync end</span></span><br><span class="line"><span class="comment"> * @crtc_vtotal: hardware mode vertical total size</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is the kernel API display mode information structure. For the</span></span><br><span class="line"><span class="comment"> * user-space version see struct drm_mode_modeinfo.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The horizontal and vertical timings are defined per the following diagram.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * ::</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *               Active                 Front           Sync           Back</span></span><br><span class="line"><span class="comment"> *              Region                 Porch                          Porch</span></span><br><span class="line"><span class="comment"> *     &lt;-----------------------&gt;&lt;----------------&gt;&lt;-------------&gt;&lt;--------------&gt;</span></span><br><span class="line"><span class="comment"> *       //////////////////////|</span></span><br><span class="line"><span class="comment"> *      ////////////////////// |</span></span><br><span class="line"><span class="comment"> *     //////////////////////  |..................               ................</span></span><br><span class="line"><span class="comment"> *                                                _______________</span></span><br><span class="line"><span class="comment"> *     &lt;----- [hv]display -----&gt;</span></span><br><span class="line"><span class="comment"> *     &lt;------------- [hv]sync_start ------------&gt;</span></span><br><span class="line"><span class="comment"> *     &lt;--------------------- [hv]sync_end ---------------------&gt;</span></span><br><span class="line"><span class="comment"> *     &lt;-------------------------------- [hv]total -----------------------------&gt;*</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This structure contains two copies of timings. First are the plain timings,</span></span><br><span class="line"><span class="comment"> * which specify the logical mode, as it would be for a progressive 1:1 scanout</span></span><br><span class="line"><span class="comment"> * at the refresh rate userspace can observe through vblank timestamps. Then</span></span><br><span class="line"><span class="comment"> * there&#x27;s the hardware timings, which are corrected for interlacing,</span></span><br><span class="line"><span class="comment"> * double-clocking and similar things. They are provided as a convenience, and</span></span><br><span class="line"><span class="comment"> * can be appropriately computed using drm_mode_set_crtcinfo().</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * For printing you can use %DRM_MODE_FMT and DRM_MODE_ARG().</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">drm_display_mode</span> &#123;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @clock:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Pixel clock in kHz.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> clock;              <span class="comment">/* in kHz */</span></span><br><span class="line">        u16 hdisplay;</span><br><span class="line">        u16 hsync_start;</span><br><span class="line">        u16 hsync_end;</span><br><span class="line">        u16 htotal;</span><br><span class="line">        u16 hskew;</span><br><span class="line">        u16 vdisplay;</span><br><span class="line">        u16 vsync_start;</span><br><span class="line">        u16 vsync_end;</span><br><span class="line">        u16 vtotal;</span><br><span class="line">        u16 vscan;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @flags:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Sync and timing flags:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_PHSYNC: horizontal sync is active high.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_NHSYNC: horizontal sync is active low.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_PVSYNC: vertical sync is active high.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_NVSYNC: vertical sync is active low.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_INTERLACE: mode is interlaced.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_DBLSCAN: mode uses doublescan.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_CSYNC: mode uses composite sync.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_PCSYNC: composite sync is active high.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_NCSYNC: composite sync is active low.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_HSKEW: hskew provided (not used?).</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_BCAST: &lt;deprecated&gt;</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_PIXMUX: &lt;deprecated&gt;</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_DBLCLK: double-clocked mode.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_CLKDIV2: half-clocked mode.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Additionally there&#x27;s flags to specify how 3D modes are packed:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_NONE: normal, non-3D mode.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_FRAME_PACKING: 2 full frames for left and right.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: interleaved like fields.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: interleaved lines.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: side-by-side full frames.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_L_DEPTH: ?</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ?</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: frame split into top and bottom</span></span><br><span class="line"><span class="comment">         *    parts.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: frame split into left and</span></span><br><span class="line"><span class="comment">         *    right parts.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 flags;</span><br><span class="line">        u32 flags;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @crtc_clock:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Actual pixel or dot clock in the hardware. This differs from the</span></span><br><span class="line"><span class="comment">         * logical @clock when e.g. using interlacing, double-clocking, stereo</span></span><br><span class="line"><span class="comment">         * modes or other fancy stuff that changes the timings and signals</span></span><br><span class="line"><span class="comment">         * actually sent over the wire.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is again in kHz.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that with digital outputs like HDMI or DP there&#x27;s usually a</span></span><br><span class="line"><span class="comment">         * massive confusion between the dot clock and the signal clock at the</span></span><br><span class="line"><span class="comment">         * bit encoding level. Especially when a 8b/10b encoding is used and the</span></span><br><span class="line"><span class="comment">         * difference is exactly a factor of 10.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> crtc_clock;</span><br><span class="line">        u16 crtc_hdisplay;</span><br><span class="line">        u16 crtc_hblank_start;</span><br><span class="line">        u16 crtc_hblank_end;</span><br><span class="line">        u16 crtc_hsync_start;</span><br><span class="line">        u16 crtc_hsync_end;</span><br><span class="line">        u16 crtc_htotal;</span><br><span class="line">        u16 crtc_hskew;</span><br><span class="line">        u16 crtc_vdisplay;</span><br><span class="line">        u16 crtc_vblank_start;</span><br><span class="line">        u16 crtc_vblank_end;</span><br><span class="line">        u16 crtc_vsync_start;</span><br><span class="line">        u16 crtc_vsync_end;</span><br><span class="line">        u16 crtc_vtotal;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @width_mm:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Addressable size of the output in mm, projectors should set this to</span></span><br><span class="line"><span class="comment">         * 0.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u16 width_mm;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @height_mm:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Addressable size of the output in mm, projectors should set this to</span></span><br><span class="line"><span class="comment">         * 0.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u16 height_mm;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @type:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * A bitmask of flags, mostly about the source of a mode. Possible flags</span></span><br><span class="line"><span class="comment">         * are:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native</span></span><br><span class="line"><span class="comment">         *    resolution of an LCD panel. There should only be one preferred</span></span><br><span class="line"><span class="comment">         *    mode per connector at any given time.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of</span></span><br><span class="line"><span class="comment">         *    them really. Drivers must set this bit for all modes they create</span></span><br><span class="line"><span class="comment">         *    and expose to userspace.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_USERDEF: Mode defined or selected via the kernel</span></span><br><span class="line"><span class="comment">         *    command line.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Plus a big list of flags which shouldn&#x27;t be used at all, but are</span></span><br><span class="line"><span class="comment">         * still around since these flags are also used in the userspace ABI.</span></span><br><span class="line"><span class="comment">         * We no longer accept modes with these types though:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, unused.</span></span><br><span class="line"><span class="comment">         *    Use DRM_MODE_TYPE_DRIVER instead.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_DEFAULT: Again a leftover, use</span></span><br><span class="line"><span class="comment">         *    DRM_MODE_TYPE_PREFERRED instead.</span></span><br><span class="line"><span class="comment">         *  - DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers</span></span><br><span class="line"><span class="comment">         *    which are stuck around for hysterical raisins only. No one has an</span></span><br><span class="line"><span class="comment">         *    idea what they were meant for. Don&#x27;t use.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u8 type;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @expose_to_userspace:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Indicates whether the mode is to be exposed to the userspace.</span></span><br><span class="line"><span class="comment">         * This is to maintain a set of exposed modes while preparing</span></span><br><span class="line"><span class="comment">         * user-mode&#x27;s list in drm_mode_getconnector ioctl. The purpose of</span></span><br><span class="line"><span class="comment">         * this only lies in the ioctl function, and is not to be used</span></span><br><span class="line"><span class="comment">         * outside the function.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> expose_to_userspace;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @head:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * struct list_head for mode lists.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">list_head</span> <span class="title">head</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @name:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Human-readable name of the mode, filled out with drm_mode_set_name().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">char</span> name[DRM_DISPLAY_MODE_LEN];</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @status:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Status of the mode, used to filter out modes not supported by the</span></span><br><span class="line"><span class="comment">         * hardware. See enum &amp;drm_mode_status.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">enum</span> <span class="title">drm_mode_status</span> <span class="title">status</span>;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @picture_aspect_ratio:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Field for setting the HDMI picture aspect ratio of a mode.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">enum</span> <span class="title">hdmi_picture_aspect</span> <span class="title">picture_aspect_ratio</span>;</span></span><br><span class="line"></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>结构体包含以下成员变量：</p>
<ul>
<li>hdisplay：水平显示大小;</li>
<li>hsync_start：水平同步起始;</li>
<li>hsync_end：水平同步结束;</li>
<li>htotal：水平总大小;</li>
<li>hskew：水平倾斜（暂不清楚具体含义）;</li>
<li>vdisplay：垂直显示大小;</li>
<li>vsync_start：垂直同步起始;</li>
<li>vsync_end：垂直同步结束;</li>
<li>vtotal：垂直总大小;</li>
<li>vscan：垂直扫描（暂不清楚具体含义）;</li>
<li>crtc_hdisplay：硬件模式的水平显示大小;</li>
<li>crtc_hblank_start：硬件模式的水平空白起始;</li>
<li>crtc_hblank_end：硬件模式的水平空白结束;</li>
<li>crtc_hsync_start：硬件模式的水平同步起始;</li>
<li>crtc_hsync_end：硬件模式的水平同步结束;</li>
<li>crtc_htotal：硬件模式的水平总大小;</li>
<li>crtc_hskew：硬件模式的水平倾斜（暂不清楚具体含义）;</li>
<li>crtc_vdisplay：硬件模式的垂直显示大小;</li>
<li>crtc_vblank_start：硬件模式的垂直空白起始;</li>
<li>crtc_vblank_end：硬件模式的垂直空白结束;</li>
<li>crtc_vsync_start：硬件模式的垂直同步起始;</li>
<li>crtc_vsync_end：硬件模式的垂直同步结束;</li>
<li>crtc_vtotal：硬件模式的垂直总大小;</li>
</ul>
<p>关于hdisplay、hsync_start、hsync_end、htotal对应着我们第一节中介绍的水平时序参数；</p>
<p>同理vdisplay、vsync_start、vsync_end、vtotal对应着垂直时序参数；</p>
<h5 id="2-1-2-struct-drm-crtc-state"><a href="#2-1-2-struct-drm-crtc-state" class="headerlink" title="2.1.2 struct drm_crtc_state"></a>2.1.2 struct drm_crtc_state</h5><p>struct drm_crtc_state用于表示crtc的状态，定义在include&#x2F;drm&#x2F;drm_crtc.h；</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * struct drm_crtc_state - mutable CRTC state</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Note that the distinction between @enable and @active is rather subtle:</span></span><br><span class="line"><span class="comment"> * Flipping @active while @enable is set without changing anything else may</span></span><br><span class="line"><span class="comment"> * never return in a failure from the &amp;drm_mode_config_funcs.atomic_check</span></span><br><span class="line"><span class="comment"> * callback. Userspace assumes that a DPMS On will always succeed. In other</span></span><br><span class="line"><span class="comment"> * words: @enable controls resource assignment, @active controls the actual</span></span><br><span class="line"><span class="comment"> * hardware state.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The three booleans active_changed, connectors_changed and mode_changed are</span></span><br><span class="line"><span class="comment"> * intended to indicate whether a full modeset is needed, rather than strictly</span></span><br><span class="line"><span class="comment"> * describing what has changed in a commit. See also:</span></span><br><span class="line"><span class="comment"> * drm_atomic_crtc_needs_modeset()</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * WARNING: Transitional helpers (like drm_helper_crtc_mode_set() or</span></span><br><span class="line"><span class="comment"> * drm_helper_crtc_mode_set_base()) do not maintain many of the derived control</span></span><br><span class="line"><span class="comment"> * state like @plane_mask so drivers not converted over to atomic helpers should</span></span><br><span class="line"><span class="comment"> * not rely on these being accurate!</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_state</span> &#123;</span></span><br><span class="line">        <span class="comment">/** @crtc: backpointer to the CRTC */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc</span> *<span class="title">crtc</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @enable: Whether the CRTC should be enabled, gates all other state.</span></span><br><span class="line"><span class="comment">         * This controls reservations of shared resources. Actual hardware state</span></span><br><span class="line"><span class="comment">         * is controlled by @active.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> enable;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @active: Whether the CRTC is actively displaying (used for DPMS).</span></span><br><span class="line"><span class="comment">         * Implies that @enable is set. The driver must not release any shared</span></span><br><span class="line"><span class="comment">         * resources if @active is set to false but @enable still true, because</span></span><br><span class="line"><span class="comment">         * userspace expects that a DPMS ON always succeeds.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Hence drivers must not consult @active in their various</span></span><br><span class="line"><span class="comment">         * &amp;drm_mode_config_funcs.atomic_check callback to reject an atomic</span></span><br><span class="line"><span class="comment">         * commit. They can consult it to aid in the computation of derived</span></span><br><span class="line"><span class="comment">         * hardware state, since even in the DPMS OFF state the display hardware</span></span><br><span class="line"><span class="comment">         * should be as much powered down as when the CRTC is completely</span></span><br><span class="line"><span class="comment">         * disabled through setting @enable to false.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> active;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @planes_changed: Planes on this crtc are updated. Used by the atomic</span></span><br><span class="line"><span class="comment">         * helpers and drivers to steer the atomic commit control flow.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> planes_changed : <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_changed: @mode or @enable has been changed. Used by the atomic</span></span><br><span class="line"><span class="comment">         * helpers and drivers to steer the atomic commit control flow. See also</span></span><br><span class="line"><span class="comment">         * drm_atomic_crtc_needs_modeset().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers are supposed to set this for any CRTC state changes that</span></span><br><span class="line"><span class="comment">         * require a full modeset. They can also reset it to false if e.g. a</span></span><br><span class="line"><span class="comment">         * @mode change can be done without a full modeset by only changing</span></span><br><span class="line"><span class="comment">         * scaler settings.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> mode_changed : <span class="number">1</span>;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @active_changed: @active has been toggled. Used by the atomic</span></span><br><span class="line"><span class="comment">         * helpers and drivers to steer the atomic commit control flow. See also</span></span><br><span class="line"><span class="comment">         * drm_atomic_crtc_needs_modeset().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> active_changed : <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @connectors_changed: Connectors to this crtc have been updated,</span></span><br><span class="line"><span class="comment">         * either in their state or routing. Used by the atomic</span></span><br><span class="line"><span class="comment">         * helpers and drivers to steer the atomic commit control flow. See also</span></span><br><span class="line"><span class="comment">         * drm_atomic_crtc_needs_modeset().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers are supposed to set this as-needed from their own atomic</span></span><br><span class="line"><span class="comment">         * check code, e.g. from &amp;drm_encoder_helper_funcs.atomic_check</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> connectors_changed : <span class="number">1</span>;</span><br><span class="line"> </span><br><span class="line"> 		<span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @zpos_changed: zpos values of planes on this crtc have been updated.</span></span><br><span class="line"><span class="comment">         * Used by the atomic helpers and drivers to steer the atomic commit</span></span><br><span class="line"><span class="comment">         * control flow.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> zpos_changed : <span class="number">1</span>;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @color_mgmt_changed: Color management properties have changed</span></span><br><span class="line"><span class="comment">         * (@gamma_lut, @degamma_lut or @ctm). Used by the atomic helpers and</span></span><br><span class="line"><span class="comment">         * drivers to steer the atomic commit control flow.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> color_mgmt_changed : <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @no_vblank:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Reflects the ability of a CRTC to send VBLANK events. This state</span></span><br><span class="line"><span class="comment">         * usually depends on the pipeline configuration. If set to true, DRM</span></span><br><span class="line"><span class="comment">         * atomic helpers will send out a fake VBLANK event during display</span></span><br><span class="line"><span class="comment">         * updates after all hardware changes have been committed. This is</span></span><br><span class="line"><span class="comment">         * implemented in drm_atomic_helper_fake_vblank().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * One usage is for drivers and/or hardware without support for VBLANK</span></span><br><span class="line"><span class="comment">         * interrupts. Such drivers typically do not initialize vblanking</span></span><br><span class="line"><span class="comment">         * (i.e., call drm_vblank_init() with the number of CRTCs). For CRTCs</span></span><br><span class="line"><span class="comment">         * without initialized vblanking, this field is set to true in</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_modeset(), and a fake VBLANK event will be</span></span><br><span class="line"><span class="comment">         * send out on each update of the display pipeline by</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_fake_vblank().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Another usage is CRTCs feeding a writeback connector operating in</span></span><br><span class="line"><span class="comment">         * oneshot mode. In this case the fake VBLANK event is only generated</span></span><br><span class="line"><span class="comment">         * when a job is queued to the writeback connector, and we want the</span></span><br><span class="line"><span class="comment">         * core to fake VBLANK events when this part of the pipeline hasn&#x27;t</span></span><br><span class="line"><span class="comment">         * changed but others had or when the CRTC and connectors are being</span></span><br><span class="line"><span class="comment">         * disabled.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * __drm_atomic_helper_crtc_duplicate_state() will not reset the value</span></span><br><span class="line"><span class="comment">         * from the current state, the CRTC driver is then responsible for</span></span><br><span class="line"><span class="comment">         * updating this field when needed.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that the combination of &amp;drm_crtc_state.event == NULL and</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.no_blank == true is valid and usually used when the</span></span><br><span class="line"><span class="comment">         * writeback connector attached to the CRTC has a new job queued. In</span></span><br><span class="line"><span class="comment">         * this case the driver will send the VBLANK event on its own when the</span></span><br><span class="line"><span class="comment">         * writeback job is complete.</span></span><br><span class="line"><span class="comment">        bool no_vblank : 1;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">        /**</span></span><br><span class="line"><span class="comment">         * @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to</span></span><br><span class="line"><span class="comment">         * this CRTC.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 plane_mask;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @connector_mask: Bitmask of drm_connector_mask(connector) of</span></span><br><span class="line"><span class="comment">         * connectors attached to this CRTC.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 connector_mask;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @encoder_mask: Bitmask of drm_encoder_mask(encoder) of encoders</span></span><br><span class="line"><span class="comment">         * attached to this CRTC.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 encoder_mask;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @adjusted_mode:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Internal display timings which can be used by the driver to handle</span></span><br><span class="line"><span class="comment">         * differences between the mode requested by userspace in @mode and what</span></span><br><span class="line"><span class="comment">         * is actually programmed into the hardware.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For drivers using &amp;drm_bridge, this stores hardware display timings</span></span><br><span class="line"><span class="comment">         * used between the CRTC and the first bridge. For other drivers, the</span></span><br><span class="line"><span class="comment">         * meaning of the adjusted_mode field is purely driver implementation</span></span><br><span class="line"><span class="comment">         * defined information, and will usually be used to store the hardware</span></span><br><span class="line"><span class="comment">         * display timings used between the CRTC and encoder blocks.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_display_mode</span> <span class="title">adjusted_mode</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Display timings requested by userspace. The driver should try to</span></span><br><span class="line"><span class="comment">         * match the refresh rate as close as possible (but note that it&#x27;s</span></span><br><span class="line"><span class="comment">         * undefined what exactly is close enough, e.g. some of the HDMI modes</span></span><br><span class="line"><span class="comment">         * only differ in less than 1% of the refresh rate). The active width</span></span><br><span class="line"><span class="comment">         * and height as observed by userspace for positioning planes must match</span></span><br><span class="line"><span class="comment">         * exactly.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For external connectors where the sink isn&#x27;t fixed (like with a</span></span><br><span class="line"><span class="comment">         * built-in panel), this mode here should match the physical mode on the</span></span><br><span class="line"><span class="comment">         * wire to the last details (i.e. including sync polarities and</span></span><br><span class="line"><span class="comment">         * everything).</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_display_mode</span> <span class="title">mode</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_blob: &amp;drm_property_blob for @mode, for exposing the mode to</span></span><br><span class="line"><span class="comment">         * atomic userspace.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_property_blob</span> *<span class="title">mode_blob</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @degamma_lut:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Lookup table for converting framebuffer pixel data before apply the</span></span><br><span class="line"><span class="comment">         * color conversion matrix @ctm. See drm_crtc_enable_color_mgmt(). The</span></span><br><span class="line"><span class="comment">         * blob (if not NULL) is an array of &amp;struct drm_color_lut.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_property_blob</span> *<span class="title">degamma_lut</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @ctm:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Color transformation matrix. See drm_crtc_enable_color_mgmt(). The</span></span><br><span class="line"><span class="comment">         * blob (if not NULL) is a &amp;struct drm_color_ctm.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_property_blob</span> *<span class="title">ctm</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @gamma_lut:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Lookup table for converting pixel data after the color conversion</span></span><br><span class="line"><span class="comment">         * matrix @ctm.  See drm_crtc_enable_color_mgmt(). The blob (if not</span></span><br><span class="line"><span class="comment">         * NULL) is an array of &amp;struct drm_color_lut.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that for mostly historical reasons stemming from Xorg heritage,</span></span><br><span class="line"><span class="comment">         * this is also used to store the color map (also sometimes color lut,</span></span><br><span class="line"><span class="comment">         * CLUT or color palette) for indexed formats like DRM_FORMAT_C8.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_property_blob</span> *<span class="title">gamma_lut</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @target_vblank:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Target vertical blank period when a page flip</span></span><br><span class="line"><span class="comment">         * should take effect.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 target_vblank;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @async_flip:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is set when DRM_MODE_PAGE_FLIP_ASYNC is set in the legacy</span></span><br><span class="line"><span class="comment">         * PAGE_FLIP IOCTL. It&#x27;s not wired up for the atomic IOCTL itself yet.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> async_flip;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @vrr_enabled:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Indicates if variable refresh rate should be enabled for the CRTC.</span></span><br><span class="line"><span class="comment">         * Support for the requested vrr state will depend on driver and</span></span><br><span class="line"><span class="comment">         * hardware capabiltiy - lacking support is not treated as failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> vrr_enabled;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @self_refresh_active:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Used by the self refresh helpers to denote when a self refresh</span></span><br><span class="line"><span class="comment">         * transition is occurring. This will be set on enable/disable callbacks</span></span><br><span class="line"><span class="comment">         * when self refresh is being enabled or disabled. In some cases, it may</span></span><br><span class="line"><span class="comment">         * not be desirable to fully shut off the crtc during self refresh.</span></span><br><span class="line"><span class="comment">         * CRTC&#x27;s can inspect this flag and determine the best course of action.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> self_refresh_active;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @scaling_filter:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Scaling filter to be applied</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">enum</span> <span class="title">drm_scaling_filter</span> <span class="title">scaling_filter</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @event:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Optional pointer to a DRM event to signal upon completion of the</span></span><br><span class="line"><span class="comment">         * state update. The driver must send out the event when the atomic</span></span><br><span class="line"><span class="comment">         * commit operation completes. There are two cases:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - The event is for a CRTC which is being disabled through this</span></span><br><span class="line"><span class="comment">         *    atomic commit. In that case the event can be send out any time</span></span><br><span class="line"><span class="comment">         *    after the hardware has stopped scanning out the current</span></span><br><span class="line"><span class="comment">         *    framebuffers. It should contain the timestamp and counter for the</span></span><br><span class="line"><span class="comment">         *    last vblank before the display pipeline was shut off. The simplest</span></span><br><span class="line"><span class="comment">         *    way to achieve that is calling drm_crtc_send_vblank_event()</span></span><br><span class="line"><span class="comment">         *    somewhen after drm_crtc_vblank_off() has been called.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - For a CRTC which is enabled at the end of the commit (even when it</span></span><br><span class="line"><span class="comment">         *    undergoes an full modeset) the vblank timestamp and counter must</span></span><br><span class="line"><span class="comment">         *    be for the vblank right before the first frame that scans out the</span></span><br><span class="line"><span class="comment">         *    new set of buffers. Again the event can only be sent out after the</span></span><br><span class="line"><span class="comment">         *    hardware has stopped scanning out the old buffers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         *  - Events for disabled CRTCs are not allowed, and drivers can ignore</span></span><br><span class="line"><span class="comment">         *    that case.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For very simple hardware without VBLANK interrupt, enabling</span></span><br><span class="line"><span class="comment">         * &amp;struct drm_crtc_state.no_vblank makes DRM&#x27;s atomic commit helpers</span></span><br><span class="line"><span class="comment">         * send a fake VBLANK event at the end of the display update after all</span></span><br><span class="line"><span class="comment">         * hardware changes have been applied. See</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_fake_vblank().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For more complex hardware this</span></span><br><span class="line"><span class="comment">         * can be handled by the drm_crtc_send_vblank_event() function,</span></span><br><span class="line"><span class="comment">         * which the driver should call on the provided event upon completion of</span></span><br><span class="line"><span class="comment">         * the atomic commit. Note that if the driver supports vblank signalling</span></span><br><span class="line"><span class="comment">         * and timestamping the vblank counters and timestamps must agree with</span></span><br><span class="line"><span class="comment">         * the ones returned from page flip events. With the current vblank</span></span><br><span class="line"><span class="comment">         * helper infrastructure this can be achieved by holding a vblank</span></span><br><span class="line"><span class="comment">         * reference while the page flip is pending, acquired through</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_get() and released with drm_crtc_vblank_put().</span></span><br><span class="line"><span class="comment">         * Drivers are free to implement their own vblank counter and timestamp</span></span><br><span class="line"><span class="comment">         * tracking though, e.g. if they have accurate timestamp registers in</span></span><br><span class="line"><span class="comment">         * hardware.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * For hardware which supports some means to synchronize vblank</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">         * interrupt delivery with committing display state there&#x27;s also</span></span><br><span class="line"><span class="comment">         * drm_crtc_arm_vblank_event(). See the documentation of that function</span></span><br><span class="line"><span class="comment">         * for a detailed discussion of the constraints it needs to be used</span></span><br><span class="line"><span class="comment">         * safely.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * If the device can&#x27;t notify of flip completion in a race-free way</span></span><br><span class="line"><span class="comment">         * at all, then the event should be armed just after the page flip is</span></span><br><span class="line"><span class="comment">         * committed. In the worst case the driver will send the event to</span></span><br><span class="line"><span class="comment">         * userspace one frame too late. This doesn&#x27;t allow for a real atomic</span></span><br><span class="line"><span class="comment">         * update, but it should avoid tearing.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_pending_vblank_event</span> *<span class="title">event</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @commit:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This tracks how the commit for this update proceeds through the</span></span><br><span class="line"><span class="comment">         * various phases. This is never cleared, except when we destroy the</span></span><br><span class="line"><span class="comment">         * state, so that subsequent commits can synchronize with previous ones.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_commit</span> *<span class="title">commit</span>;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/** @state: backpointer to global drm_atomic_state */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_atomic_state</span> *<span class="title">state</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h4 id="2-2-操作函数"><a href="#2-2-操作函数" class="headerlink" title="2.2 操作函数"></a>2.2 操作函数</h4><h5 id="2-2-1-struct-drm-crtc-funcs"><a href="#2-2-1-struct-drm-crtc-funcs" class="headerlink" title="2.2.1 struct drm_crtc_funcs"></a>2.2.1 struct drm_crtc_funcs</h5><p>struct drm_crtc_funcs用于定义与 CRTC相关的函数和操作，该结构体包含了一系列函数指针，用于实现包括模式设置、帧缓冲区映射、显示控制等功能。定义在include&#x2F;drm&#x2F;drm_crtc.h；</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * struct drm_crtc_funcs - control CRTCs for a given device</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The drm_crtc_funcs structure is the central CRTC management structure</span></span><br><span class="line"><span class="comment"> * in the DRM.  Each CRTC controls one or more connectors (note that the name</span></span><br><span class="line"><span class="comment"> * CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc.</span></span><br><span class="line"><span class="comment"> * connectors, not just CRTs).</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Each driver is responsible for filling out this structure at startup time,</span></span><br><span class="line"><span class="comment"> * in addition to providing other modesetting features, like i2c and DDC</span></span><br><span class="line"><span class="comment"> * bus accessors.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_funcs</span> &#123;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @reset:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Reset CRTC hardware and software state to off. This function isn&#x27;t</span></span><br><span class="line"><span class="comment">         * called by the core directly, only through drm_mode_config_reset().</span></span><br><span class="line"><span class="comment">         * It&#x27;s not a helper hook only for historical reasons.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Atomic drivers can use drm_atomic_helper_crtc_reset() to reset</span></span><br><span class="line"><span class="comment">         * atomic state using this hook.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*reset)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor_set:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Update the cursor image. The cursor position is relative to the CRTC</span></span><br><span class="line"><span class="comment">         * and can be partially or fully outside of the visible area.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that contrary to all other KMS functions the legacy cursor entry</span></span><br><span class="line"><span class="comment">         * points don&#x27;t take a framebuffer object, but instead take directly a</span></span><br><span class="line"><span class="comment">         * raw buffer object id from the driver&#x27;s buffer manager (which is</span></span><br><span class="line"><span class="comment">         * either GEM or TTM for current drivers).</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This entry point is deprecated, drivers should instead implement</span></span><br><span class="line"><span class="comment">         * universal plane support and register a proper cursor plane using</span></span><br><span class="line"><span class="comment">         * drm_crtc_init_with_planes().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*cursor_set)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="keyword">struct</span> drm_file *file_priv,</span><br><span class="line">                          <span class="type">uint32_t</span> handle, <span class="type">uint32_t</span> width, <span class="type">uint32_t</span> height);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor_set2:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Update the cursor image, including hotspot information. The hotspot</span></span><br><span class="line"><span class="comment">         * must not affect the cursor position in CRTC coordinates, but is only</span></span><br><span class="line"><span class="comment">         * meant as a hint for virtualized display hardware to coordinate the</span></span><br><span class="line"><span class="comment">         * guests and hosts cursor position. The cursor hotspot is relative to</span></span><br><span class="line"><span class="comment">         * the cursor image. Otherwise this works exactly like @cursor_set.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This entry point is deprecated, drivers should instead implement</span></span><br><span class="line"><span class="comment">         * universal plane support and register a proper cursor plane using</span></span><br><span class="line"><span class="comment">         * drm_crtc_init_with_planes().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*cursor_set2)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="keyword">struct</span> drm_file *file_priv,</span><br><span class="line">                           <span class="type">uint32_t</span> handle, <span class="type">uint32_t</span> width, <span class="type">uint32_t</span> height,</span><br><span class="line">                           <span class="type">int32_t</span> hot_x, <span class="type">int32_t</span> hot_y);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @cursor_move:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Update the cursor position. The cursor does not need to be visible</span></span><br><span class="line"><span class="comment">         * when this hook is called.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This entry point is deprecated, drivers should instead implement</span></span><br><span class="line"><span class="comment">         * universal plane support and register a proper cursor plane using</span></span><br><span class="line"><span class="comment">         * drm_crtc_init_with_planes().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*cursor_move)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="type">int</span> x, <span class="type">int</span> y);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @gamma_set:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Set gamma on the CRTC.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Atomic drivers who want to support gamma tables should implement the</span></span><br><span class="line"><span class="comment">         * atomic color management support, enabled by calling</span></span><br><span class="line"><span class="comment">         * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma</span></span><br><span class="line"><span class="comment">         * interface through the drm_atomic_helper_legacy_gamma_set()</span></span><br><span class="line"><span class="comment">         * compatibility implementation.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*gamma_set)(<span class="keyword">struct</span> drm_crtc *crtc, u16 *r, u16 *g, u16 *b,</span><br><span class="line">                         <span class="type">uint32_t</span> size,</span><br><span class="line">                         <span class="keyword">struct</span> drm_modeset_acquire_ctx *ctx);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @destroy:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Clean up CRTC resources. This is only called at driver unload time</span></span><br><span class="line"><span class="comment">         * through drm_mode_config_cleanup() since a CRTC cannot be hotplugged</span></span><br><span class="line"><span class="comment">         * in DRM.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*destroy)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @set_config:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is the main legacy entry point to change the modeset state on a</span></span><br><span class="line"><span class="comment">         * CRTC. All the details of the desired configuration are passed in a</span></span><br><span class="line"><span class="comment">         * &amp;struct drm_mode_set - see there for details.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers implementing atomic modeset should use</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_set_config() to implement this hook.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*set_config)(<span class="keyword">struct</span> drm_mode_set *<span class="built_in">set</span>,</span><br><span class="line">                          <span class="keyword">struct</span> drm_modeset_acquire_ctx *ctx);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @page_flip:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Legacy entry point to schedule a flip to the given framebuffer.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Page flipping is a synchronization mechanism that replaces the frame</span></span><br><span class="line"><span class="comment">         * buffer being scanned out by the CRTC with a new frame buffer during</span></span><br><span class="line"><span class="comment">         * vertical blanking, avoiding tearing (except when requested otherwise</span></span><br><span class="line"><span class="comment">         * through the DRM_MODE_PAGE_FLIP_ASYNC flag). When an application</span></span><br><span class="line"><span class="comment">         * requests a page flip the DRM core verifies that the new frame buffer</span></span><br><span class="line"><span class="comment">         * is large enough to be scanned out by the CRTC in the currently</span></span><br><span class="line"><span class="comment">         * configured mode and then calls this hook with a pointer to the new</span></span><br><span class="line"><span class="comment">         * frame buffer.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * The driver must wait for any pending rendering to the new framebuffer</span></span><br><span class="line"><span class="comment">         * to complete before executing the flip. It should also wait for any</span></span><br><span class="line"><span class="comment">         * pending rendering from other drivers if the underlying buffer is a</span></span><br><span class="line"><span class="comment">         * shared dma-buf.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * An application can request to be notified when the page flip has</span></span><br><span class="line"><span class="comment">         * completed. The drm core will supply a &amp;struct drm_event in the event</span></span><br><span class="line"><span class="comment">         * parameter in this case. This can be handled by the</span></span><br><span class="line"><span class="comment">         * drm_crtc_send_vblank_event() function, which the driver should call on</span></span><br><span class="line"><span class="comment">         * the provided event upon completion of the flip. Note that if</span></span><br><span class="line"><span class="comment">         * the driver supports vblank signalling and timestamping the vblank</span></span><br><span class="line"><span class="comment">         * counters and timestamps must agree with the ones returned from page</span></span><br><span class="line"><span class="comment">         * flip events. With the current vblank helper infrastructure this can</span></span><br><span class="line"><span class="comment">         * be achieved by holding a vblank reference while the page flip is</span></span><br><span class="line"><span class="comment">         * pending, acquired through drm_crtc_vblank_get() and released with</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_put(). Drivers are free to implement their own vblank</span></span><br><span class="line"><span class="comment">         * counter and timestamp tracking though, e.g. if they have accurate</span></span><br><span class="line"><span class="comment">         * timestamp registers in hardware.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Very early versions of the KMS ABI mandated that the driver must</span></span><br><span class="line"><span class="comment">         * block (but not reject) any rendering to the old framebuffer until the</span></span><br><span class="line"><span class="comment">         * flip operation has completed and the old framebuffer is no longer</span></span><br><span class="line"><span class="comment">         * visible. This requirement has been lifted, and userspace is instead</span></span><br><span class="line"><span class="comment">         * expected to request delivery of an event and wait with recycling old</span></span><br><span class="line"><span class="comment">         * buffers until such has been received.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure. Note that if a</span></span><br><span class="line"><span class="comment">         * page flip operation is already pending the callback should return</span></span><br><span class="line"><span class="comment">         * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode</span></span><br><span class="line"><span class="comment">         * or just runtime disabled through DPMS respectively the new atomic</span></span><br><span class="line"><span class="comment">         * &quot;ACTIVE&quot; state) should result in an -EINVAL error code. Note that</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_page_flip() checks this already for atomic drivers.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*page_flip)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                         <span class="keyword">struct</span> drm_framebuffer *fb,</span><br><span class="line">                         <span class="keyword">struct</span> drm_pending_vblank_event *event,</span><br><span class="line">                         <span class="type">uint32_t</span> flags,</span><br><span class="line">                         <span class="keyword">struct</span> drm_modeset_acquire_ctx *ctx);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @page_flip_target:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Same as @page_flip but with an additional parameter specifying the</span></span><br><span class="line"><span class="comment">         * absolute target vertical blank period (as reported by</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_count()) when the flip should take effect.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that the core code calls drm_crtc_vblank_get before this entry</span></span><br><span class="line"><span class="comment">         * point, and will call drm_crtc_vblank_put if this entry point returns</span></span><br><span class="line"><span class="comment">         * any non-0 error code. It&#x27;s the driver&#x27;s responsibility to call</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_put after this entry point returns 0, typically when</span></span><br><span class="line"><span class="comment">         * the flip completes.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*page_flip_target)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                <span class="keyword">struct</span> drm_framebuffer *fb,</span><br><span class="line">                                <span class="keyword">struct</span> drm_pending_vblank_event *event,</span><br><span class="line">                                <span class="type">uint32_t</span> flags, <span class="type">uint32_t</span> target,</span><br><span class="line">                                <span class="keyword">struct</span> drm_modeset_acquire_ctx *ctx);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @set_property:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is the legacy entry point to update a property attached to the</span></span><br><span class="line"><span class="comment">         * CRTC.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support any legacy</span></span><br><span class="line"><span class="comment">         * driver-private properties. For atomic drivers it is not used because</span></span><br><span class="line"><span class="comment">         * property handling is done entirely in the DRM core.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*set_property)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                            <span class="keyword">struct</span> drm_property *property, <span class="type">uint64_t</span> val);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_duplicate_state:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Duplicate the current atomic state for this CRTC and return it.</span></span><br><span class="line"><span class="comment">         * The core and helpers guarantee that any atomic state duplicated with</span></span><br><span class="line"><span class="comment">         * this hook and still owned by the caller (i.e. not transferred to the</span></span><br><span class="line"><span class="comment">         * driver by calling &amp;drm_mode_config_funcs.atomic_commit) will be</span></span><br><span class="line"><span class="comment">         * cleaned up by calling the @atomic_destroy_state hook in this</span></span><br><span class="line"><span class="comment">         * structure.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is mandatory for atomic drivers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Atomic drivers which don&#x27;t subclass &amp;struct drm_crtc_state should use</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the</span></span><br><span class="line"><span class="comment">         * state structure to extend it with driver-private state should use</span></span><br><span class="line"><span class="comment">         * __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is</span></span><br><span class="line"><span class="comment">         * duplicated in a consistent fashion across drivers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * It is an error to call this hook before &amp;drm_crtc.state has been</span></span><br><span class="line"><span class="comment">         * initialized correctly.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * If the duplicate state references refcounted resources this hook must</span></span><br><span class="line"><span class="comment">         * acquire a reference for each of them. The driver must release these</span></span><br><span class="line"><span class="comment">         * references again in @atomic_destroy_state.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Duplicated atomic state or NULL when the allocation failed.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_state</span> *(*<span class="title">atomic_duplicate_state</span>)(<span class="keyword">struct</span> <span class="title">drm_crtc</span> *<span class="title">crtc</span>);</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_destroy_state:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Destroy a state duplicated with @atomic_duplicate_state and release</span></span><br><span class="line"><span class="comment">         * or unreference all resources it references</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is mandatory for atomic drivers.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*atomic_destroy_state)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                     <span class="keyword">struct</span> drm_crtc_state *state);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_set_property:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Decode a driver-private property value and store the decoded value</span></span><br><span class="line"><span class="comment">         * into the passed-in state structure. Since the atomic core decodes all</span></span><br><span class="line"><span class="comment">         * standardized properties (even for extensions beyond the core set of</span></span><br><span class="line"><span class="comment">         * properties which might not be implemented by all drivers) this</span></span><br><span class="line"><span class="comment">         * requires drivers to subclass the state structure.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Such driver-private properties should really only be implemented for</span></span><br><span class="line"><span class="comment">         * truly hardware/vendor specific state. Instead it is preferred to</span></span><br><span class="line"><span class="comment">         * standardize atomic extension and decode the properties used to expose</span></span><br><span class="line"><span class="comment">         * such an extension in the core.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Do not call this function directly, use</span></span><br><span class="line"><span class="comment">         * drm_atomic_crtc_set_property() instead.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support any</span></span><br><span class="line"><span class="comment">         * driver-private atomic properties.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is called in the state assembly phase of atomic</span></span><br><span class="line"><span class="comment">         * modesets, which can be aborted for any reason (including on</span></span><br><span class="line"><span class="comment">         * userspace&#x27;s request to just check whether a configuration would be</span></span><br><span class="line"><span class="comment">         * possible). Drivers MUST NOT touch any persistent state (hardware or</span></span><br><span class="line"><span class="comment">         * software) or data structures except the passed in @state parameter.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Also since userspace controls in which order properties are set this</span></span><br><span class="line"><span class="comment">         * function must not do any input validation (since the state update is</span></span><br><span class="line"><span class="comment">         * incomplete and hence likely inconsistent). Instead any such input</span></span><br><span class="line"><span class="comment">         * validation must be done in the various atomic_check callbacks.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 if the property has been found, -EINVAL if the property isn&#x27;t</span></span><br><span class="line"><span class="comment">         * implemented by the driver (which should never happen, the core only</span></span><br><span class="line"><span class="comment">         * asks for properties attached to this CRTC). No other validation is</span></span><br><span class="line"><span class="comment">         * allowed by the driver. The core already checks that the property</span></span><br><span class="line"><span class="comment">         * value is within the range (integer, valid enum value, ...) the driver</span></span><br><span class="line"><span class="comment">         * set when registering the property.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*atomic_set_property)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                   <span class="keyword">struct</span> drm_crtc_state *state,</span><br><span class="line">                                   <span class="keyword">struct</span> drm_property *property,</span><br><span class="line">                                   <span class="type">uint64_t</span> val);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_get_property:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Reads out the decoded driver-private property. This is used to</span></span><br><span class="line"><span class="comment">         * implement the GETCRTC IOCTL.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Do not call this function directly, use</span></span><br><span class="line"><span class="comment">         * drm_atomic_crtc_get_property() instead.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support any</span></span><br><span class="line"><span class="comment">         * driver-private atomic properties.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success, -EINVAL if the property isn&#x27;t implemented by the</span></span><br><span class="line"><span class="comment">         * driver (which should never happen, the core only asks for</span></span><br><span class="line"><span class="comment">         * properties attached to this CRTC).</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*atomic_get_property)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                   <span class="type">const</span> <span class="keyword">struct</span> drm_crtc_state *state,</span><br><span class="line">                                   <span class="keyword">struct</span> drm_property *property,</span><br><span class="line">                                   <span class="type">uint64_t</span> *val);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @late_register:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This optional hook can be used to register additional userspace</span></span><br><span class="line"><span class="comment">         * interfaces attached to the crtc like debugfs interfaces.</span></span><br><span class="line"><span class="comment">         * It is called late in the driver load sequence from drm_dev_register().</span></span><br><span class="line"><span class="comment">         * Everything added from this callback should be unregistered in</span></span><br><span class="line"><span class="comment">         * the early_unregister callback.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success, or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*late_register)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @early_unregister:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This optional hook should be used to unregister the additional</span></span><br><span class="line"><span class="comment">         * userspace interfaces attached to the crtc from</span></span><br><span class="line"><span class="comment">         * @late_register. It is called from drm_dev_unregister(),</span></span><br><span class="line"><span class="comment">         * early in the driver unload sequence to disable userspace access</span></span><br><span class="line"><span class="comment">         * before data structures are torndown.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*early_unregister)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @set_crc_source:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Changes the source of CRC checksums of frames at the request of</span></span><br><span class="line"><span class="comment">         * userspace, typically for testing purposes. The sources available are</span></span><br><span class="line"><span class="comment">         * specific of each driver and a %NULL value indicates that CRC</span></span><br><span class="line"><span class="comment">         * generation is to be switched off.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * When CRC generation is enabled, the driver should call</span></span><br><span class="line"><span class="comment">         * drm_crtc_add_crc_entry() at each frame, providing any information</span></span><br><span class="line"><span class="comment">         * that characterizes the frame contents in the crcN arguments, as</span></span><br><span class="line"><span class="comment">         * provided from the configured source. Drivers must accept an &quot;auto&quot;</span></span><br><span class="line"><span class="comment">         * source name that will select a default source for this CRTC.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This may trigger an atomic modeset commit if necessary, to enable CRC</span></span><br><span class="line"><span class="comment">         * generation.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that &quot;auto&quot; can depend upon the current modeset configuration,</span></span><br><span class="line"><span class="comment">         * e.g. it could pick an encoder or output specific CRC sampling point.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support any CRC</span></span><br><span class="line"><span class="comment">         * generation functionality.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*set_crc_source)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="type">const</span> <span class="type">char</span> *source);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @verify_crc_source:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * verifies the source of CRC checksums of frames before setting the</span></span><br><span class="line"><span class="comment">         * source for CRC and during crc open. Source parameter can be NULL</span></span><br><span class="line"><span class="comment">         * while disabling crc source.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support any CRC</span></span><br><span class="line"><span class="comment">         * generation functionality.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*verify_crc_source)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="type">const</span> <span class="type">char</span> *source,</span><br><span class="line">                                 <span class="type">size_t</span> *values_cnt);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @get_crc_sources:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Driver callback for getting a list of all the available sources for</span></span><br><span class="line"><span class="comment">         * CRC generation. This callback depends upon verify_crc_source, So</span></span><br><span class="line"><span class="comment">         * verify_crc_source callback should be implemented before implementing</span></span><br><span class="line"><span class="comment">         * this. Driver can pass full list of available crc sources, this</span></span><br><span class="line"><span class="comment">         * callback does the verification on each crc-source before passing it</span></span><br><span class="line"><span class="comment">         * to userspace.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional if the driver does not support exporting of</span></span><br><span class="line"><span class="comment">         * possible CRC sources list.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * a constant character pointer to the list of all the available CRC</span></span><br><span class="line"><span class="comment">         * sources. On failure driver should return NULL. count should be</span></span><br><span class="line"><span class="comment">         * updated with number of sources in list. if zero we don&#x27;t process any</span></span><br><span class="line"><span class="comment">         * source from the list.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *<span class="type">const</span> *(*get_crc_sources)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                              <span class="type">size_t</span> *count);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_print_state:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * If driver subclasses &amp;struct drm_crtc_state, it should implement</span></span><br><span class="line"><span class="comment">         * this optional hook for printing additional driver specific state.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Do not call this directly, use drm_atomic_crtc_print_state()</span></span><br><span class="line"><span class="comment">         * instead.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*atomic_print_state)(<span class="keyword">struct</span> drm_printer *p,</span><br><span class="line">                                   <span class="type">const</span> <span class="keyword">struct</span> drm_crtc_state *state);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @get_vblank_counter:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Driver callback for fetching a raw hardware vblank counter for the</span></span><br><span class="line"><span class="comment">         * CRTC. It&#x27;s meant to be used by new drivers as the replacement of</span></span><br><span class="line"><span class="comment">         * &amp;drm_driver.get_vblank_counter hook.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional. If a device doesn&#x27;t have a hardware</span></span><br><span class="line"><span class="comment">         * counter, the driver can simply leave the hook as NULL. The DRM core</span></span><br><span class="line"><span class="comment">         * will account for missed vblank events while interrupts where disabled</span></span><br><span class="line"><span class="comment">         * based on system timestamps.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Wraparound handling and loss of events due to modesetting is dealt</span></span><br><span class="line"><span class="comment">         * with in the DRM core code, as long as drivers call</span></span><br><span class="line"><span class="comment">         * drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or</span></span><br><span class="line"><span class="comment">         * enabling a CRTC.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * See also &amp;drm_device.vblank_disable_immediate and</span></span><br><span class="line"><span class="comment">         * &amp;drm_device.max_vblank_count.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Raw vblank counter value.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        u32 (*get_vblank_counter)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @enable_vblank:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Enable vblank interrupts for the CRTC. It&#x27;s meant to be used by</span></span><br><span class="line"><span class="comment">         * new drivers as the replacement of &amp;drm_driver.enable_vblank hook.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Zero on success, appropriate errno if the vblank interrupt cannot</span></span><br><span class="line"><span class="comment">         * be enabled.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*enable_vblank)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @disable_vblank:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Disable vblank interrupts for the CRTC. It&#x27;s meant to be used by</span></span><br><span class="line"><span class="comment">         * new drivers as the replacement of &amp;drm_driver.disable_vblank hook.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*disable_vblank)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @get_vblank_timestamp:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Called by drm_get_last_vbltimestamp(). Should return a precise</span></span><br><span class="line"><span class="comment">         * timestamp when the most recent vblank interval ended or will end.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Specifically, the timestamp in @vblank_time should correspond as</span></span><br><span class="line"><span class="comment">         * closely as possible to the time when the first video scanline of</span></span><br><span class="line"><span class="comment">         * the video frame after the end of vblank will start scanning out,</span></span><br><span class="line"><span class="comment">         * the time immediately after end of the vblank interval. If the</span></span><br><span class="line"><span class="comment">         * @crtc is currently inside vblank, this will be a time in the future.</span></span><br><span class="line"><span class="comment">         * If the @crtc is currently scanning out a frame, this will be the</span></span><br><span class="line"><span class="comment">         * past start time of the current scanout. This is meant to adhere</span></span><br><span class="line"><span class="comment">         * to the OpenML OML_sync_control extension specification.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Parameters:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * crtc:</span></span><br><span class="line"><span class="comment">         *     CRTC for which timestamp should be returned.</span></span><br><span class="line"><span class="comment">         * max_error:</span></span><br><span class="line"><span class="comment">         *     Maximum allowable timestamp error in nanoseconds.</span></span><br><span class="line"><span class="comment">         *     Implementation should strive to provide timestamp</span></span><br><span class="line"><span class="comment">         *     with an error of at most max_error nanoseconds.</span></span><br><span class="line"><span class="comment">         *     Returns true upper bound on error for timestamp.</span></span><br><span class="line"><span class="comment">         * vblank_time:</span></span><br><span class="line"><span class="comment">         *     Target location for returned vblank timestamp.</span></span><br><span class="line"><span class="comment">         * in_vblank_irq:</span></span><br><span class="line"><span class="comment">         *     True when called from drm_crtc_handle_vblank().  Some drivers</span></span><br><span class="line"><span class="comment">         *     need to apply some workarounds for gpu-specific vblank irq quirks</span></span><br><span class="line"><span class="comment">         *     if flag is set.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * True on success, false on failure, which means the core should</span></span><br><span class="line"><span class="comment">         * fallback to a simple timestamp taken in drm_crtc_handle_vblank().</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> (*get_vblank_timestamp)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                     <span class="type">int</span> *max_error,</span><br><span class="line">                                     <span class="type">ktime_t</span> *vblank_time,</span><br><span class="line">                                     <span class="type">bool</span> in_vblank_irq);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>这里定义了一大堆回调函数：</p>
<ul>
<li>reset：用于将CRTC硬件和软件重置为关闭状态，这个函数不会直接调用，只会通过drm_mode_config_reset()调用；</li>
<li>cursor_set：更新光标图像，光标位置是相对于CRTC，并且可以部分或完全位于可见区域之外；</li>
<li>cursor_set2：更新光标图像，包括热点信息；</li>
<li>cursor_move：更新光标位置。在调用此钩子时，光标不需要可见；</li>
<li>gamma_set：在CRTC上设置gamma；</li>
<li>destroy：清理CRTC资源；</li>
<li>set_config：改变modeset state；</li>
<li>page_flip：用于反转给定的framebuffer；</li>
<li>…</li>
</ul>
<h5 id="2-2-2-struct-drm-crtc-helper-funcs"><a href="#2-2-2-struct-drm-crtc-helper-funcs" class="headerlink" title="2.2.2 struct drm_crtc_helper_funcs"></a>2.2.2 struct drm_crtc_helper_funcs</h5><p>struct drm_crtc_helper_funcs用于定义与 CRTC 助手函数相关的操作。这些助手函数提供了一些辅助性的操作，如时序生成、同步信号发送、格式转换等，以便更好地协助实现扫描输出帧缓冲区内容的功能。定义在include&#x2F;drm&#x2F;drm_modeset_helper_vtables.h；</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * struct drm_crtc_helper_funcs - helper operations for CRTCs</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * These hooks are used by the legacy CRTC helpers, the transitional plane</span></span><br><span class="line"><span class="comment"> * helpers and the new atomic modesetting helpers.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">drm_crtc_helper_funcs</span> &#123;</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @dpms:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Callback to control power levels on the CRTC.  If the mode passed in</span></span><br><span class="line"><span class="comment">         * is unsupported, the provider must use the next lowest power level.</span></span><br><span class="line"><span class="comment">         * This is used by the legacy CRTC helpers to implement DPMS</span></span><br><span class="line"><span class="comment">         * functionality in drm_helper_connector_dpms().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is also used to disable a CRTC by calling it with</span></span><br><span class="line"><span class="comment">         * DRM_MODE_DPMS_OFF if the @disable hook isn&#x27;t used.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the legacy CRTC helpers.  Atomic helpers</span></span><br><span class="line"><span class="comment">         * also support using this hook for enabling and disabling a CRTC to</span></span><br><span class="line"><span class="comment">         * facilitate transitions to atomic, but it is deprecated. Instead</span></span><br><span class="line"><span class="comment">         * @atomic_enable and @atomic_disable should be used.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*dpms)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="type">int</span> mode);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @prepare:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback should prepare the CRTC for a subsequent modeset, which</span></span><br><span class="line"><span class="comment">         * in practice means the driver should disable the CRTC if it is</span></span><br><span class="line"><span class="comment">         * running. Most drivers ended up implementing this by calling their</span></span><br><span class="line"><span class="comment">         * @dpms hook with DRM_MODE_DPMS_OFF.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the legacy CRTC helpers.  Atomic helpers</span></span><br><span class="line"><span class="comment">         * also support using this hook for disabling a CRTC to facilitate</span></span><br><span class="line"><span class="comment">         * transitions to atomic, but it is deprecated. Instead @atomic_disable</span></span><br><span class="line"><span class="comment">         * should be used.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*prepare)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @commit:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback should commit the new mode on the CRTC after a modeset,</span></span><br><span class="line"><span class="comment">         * which in practice means the driver should enable the CRTC.  Most</span></span><br><span class="line"><span class="comment">         * drivers ended up implementing this by calling their @dpms hook with</span></span><br><span class="line"><span class="comment">         * DRM_MODE_DPMS_ON.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the legacy CRTC helpers.  Atomic helpers</span></span><br><span class="line"><span class="comment">         * also support using this hook for enabling a CRTC to facilitate</span></span><br><span class="line"><span class="comment">         * transitions to atomic, but it is deprecated. Instead @atomic_enable</span></span><br><span class="line"><span class="comment">         * should be used.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*commit)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_valid:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used to check if a specific mode is valid in this</span></span><br><span class="line"><span class="comment">         * crtc. This should be implemented if the crtc has some sort of</span></span><br><span class="line"><span class="comment">         * restriction in the modes it can display. For example, a given crtc</span></span><br><span class="line"><span class="comment">         * may be responsible to set a clock value. If the clock can not</span></span><br><span class="line"><span class="comment">         * produce all the values for the available modes then this callback</span></span><br><span class="line"><span class="comment">         * can be used to restrict the number of modes to only the ones that</span></span><br><span class="line"><span class="comment">         * can be displayed.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is used by the probe helpers to filter the mode list in</span></span><br><span class="line"><span class="comment">         * drm_helper_probe_single_connector_modes(), and it is used by the</span></span><br><span class="line"><span class="comment">         * atomic helpers to validate modes supplied by userspace in</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_modeset().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Since this function is both called from the check phase of an atomic</span></span><br><span class="line"><span class="comment">         * commit, and the mode validation in the probe paths it is not allowed</span></span><br><span class="line"><span class="comment">         * to look at anything else but the passed-in mode, and validate it</span></span><br><span class="line"><span class="comment">         * against configuration-invariant hardward constraints. Any further</span></span><br><span class="line"><span class="comment">         * limits which depend upon the configuration can only be checked in</span></span><br><span class="line"><span class="comment">         * @mode_fixup or @atomic_check.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * drm_mode_status Enum</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="keyword">enum</span> <span class="title function_">drm_mode_status</span> <span class="params">(*mode_valid)</span><span class="params">(<span class="keyword">struct</span> drm_crtc *crtc,</span></span><br><span class="line"><span class="params">                                           <span class="type">const</span> <span class="keyword">struct</span> drm_display_mode *mode)</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_fixup:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used to validate a mode. The parameter mode is the</span></span><br><span class="line"><span class="comment">         * display mode that userspace requested, adjusted_mode is the mode the</span></span><br><span class="line"><span class="comment">         * encoders need to be fed with. Note that this is the inverse semantics</span></span><br><span class="line"><span class="comment">         * of the meaning for the &amp;drm_encoder and &amp;drm_bridge_funcs.mode_fixup</span></span><br><span class="line"><span class="comment">         * vfunc. If the CRTC cannot support the requested conversion from mode</span></span><br><span class="line"><span class="comment">         * to adjusted_mode it should reject the modeset. See also</span></span><br><span class="line"><span class="comment">         * &amp;drm_crtc_state.adjusted_mode for more details.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is used by both legacy CRTC helpers and atomic helpers.</span></span><br><span class="line"><span class="comment">         * With atomic helpers it is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is called in the check phase of atomic modesets, which</span></span><br><span class="line"><span class="comment">         * can be aborted for any reason (including on userspace&#x27;s request to</span></span><br><span class="line"><span class="comment">         * just check whether a configuration would be possible). Atomic drivers</span></span><br><span class="line"><span class="comment">         * MUST NOT touch any persistent state (hardware or software) or data</span></span><br><span class="line"><span class="comment">         * structures except the passed in adjusted_mode parameter.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This is in contrast to the legacy CRTC helpers where this was</span></span><br><span class="line"><span class="comment">         * allowed.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Atomic drivers which need to inspect and adjust more state should</span></span><br><span class="line"><span class="comment">         * instead use the @atomic_check callback, but note that they&#x27;re not</span></span><br><span class="line"><span class="comment">         * perfectly equivalent: @mode_valid is called from</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_modeset(), but @atomic_check is called from</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_planes(), because originally it was meant for</span></span><br><span class="line"><span class="comment">         * plane update checks only.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Also beware that userspace can request its own custom modes, neither</span></span><br><span class="line"><span class="comment">         * core nor helpers filter modes to the list of probe modes reported by</span></span><br><span class="line"><span class="comment">         * the GETCONNECTOR IOCTL and stored in &amp;drm_connector.modes. To ensure</span></span><br><span class="line"><span class="comment">         * that modes are filtered consistently put any CRTC constraints and</span></span><br><span class="line"><span class="comment">         * limits checks into @mode_valid.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * True if an acceptable configuration is possible, false if the modeset</span></span><br><span class="line"><span class="comment">         * operation should be rejected.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> (*mode_fixup)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                           <span class="type">const</span> <span class="keyword">struct</span> drm_display_mode *mode,</span><br><span class="line">                           <span class="keyword">struct</span> drm_display_mode *adjusted_mode);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_set:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the legacy CRTC helpers to set a new mode,</span></span><br><span class="line"><span class="comment">         * position and framebuffer. Since it ties the primary plane to every</span></span><br><span class="line"><span class="comment">         * mode change it is incompatible with universal plane support. And</span></span><br><span class="line"><span class="comment">         * since it can&#x27;t update other planes it&#x27;s incompatible with atomic</span></span><br><span class="line"><span class="comment">         * modeset support.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is only used by CRTC helpers and deprecated.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*mode_set)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="keyword">struct</span> drm_display_mode *mode,</span><br><span class="line">                        <span class="keyword">struct</span> drm_display_mode *adjusted_mode, <span class="type">int</span> x, <span class="type">int</span> y,</span><br><span class="line">                        <span class="keyword">struct</span> drm_framebuffer *old_fb);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_set_nofb:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used to update the display mode of a CRTC without</span></span><br><span class="line"><span class="comment">         * changing anything of the primary plane configuration. This fits the</span></span><br><span class="line"><span class="comment">         * requirement of atomic and hence is used by the atomic helpers. It is</span></span><br><span class="line"><span class="comment">         * also used by the transitional plane helpers to implement a</span></span><br><span class="line"><span class="comment">         * @mode_set hook in drm_helper_crtc_mode_set().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that the display pipe is completely off when this function is</span></span><br><span class="line"><span class="comment">         * called. Atomic drivers which need hardware to be running before they</span></span><br><span class="line"><span class="comment">         * program the new display mode (e.g. because they implement runtime PM)</span></span><br><span class="line"><span class="comment">         * should not use this hook. This is because the helper library calls</span></span><br><span class="line"><span class="comment">         * this hook only once per mode change and not every time the display</span></span><br><span class="line"><span class="comment">         * pipeline is suspended using either DPMS or the new &quot;ACTIVE&quot; property.</span></span><br><span class="line"><span class="comment">         * Which means register values set in this callback might get reset when</span></span><br><span class="line"><span class="comment">         * the CRTC is suspended, but not restored.  Such drivers should instead</span></span><br><span class="line"><span class="comment">         * move all their CRTC setup into the @atomic_enable callback.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*mode_set_nofb)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_set_base:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the legacy CRTC helpers to set a new</span></span><br><span class="line"><span class="comment">         * framebuffer and scanout position. It is optional and used as an</span></span><br><span class="line"><span class="comment">         * optimized fast-path instead of a full mode set operation with all the</span></span><br><span class="line"><span class="comment">         * resulting flickering. If it is not present</span></span><br><span class="line"><span class="comment">         * drm_crtc_helper_set_config() will fall back to a full modeset, using</span></span><br><span class="line"><span class="comment">         * the @mode_set callback. Since it can&#x27;t update other planes it&#x27;s</span></span><br><span class="line"><span class="comment">         * incompatible with atomic modeset support.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is only used by the CRTC helpers and deprecated.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*mode_set_base)(<span class="keyword">struct</span> drm_crtc *crtc, <span class="type">int</span> x, <span class="type">int</span> y,</span><br><span class="line">                             <span class="keyword">struct</span> drm_framebuffer *old_fb);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @mode_set_base_atomic:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the fbdev helpers to set a new framebuffer</span></span><br><span class="line"><span class="comment">         * and scanout without sleeping, i.e. from an atomic calling context. It</span></span><br><span class="line"><span class="comment">         * is only used to implement kgdb support.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is optional and only needed for kgdb support in the fbdev</span></span><br><span class="line"><span class="comment">         * helpers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success or a negative error code on failure.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*mode_set_base_atomic)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                    <span class="keyword">struct</span> drm_framebuffer *fb, <span class="type">int</span> x, <span class="type">int</span> y,</span><br><span class="line">                                    <span class="keyword">enum</span> mode_set_atomic);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @disable:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback should be used to disable the CRTC. With the atomic</span></span><br><span class="line"><span class="comment">         * drivers it is called after all encoders connected to this CRTC have</span></span><br><span class="line"><span class="comment">         * been shut off already using their own</span></span><br><span class="line"><span class="comment">         * &amp;drm_encoder_helper_funcs.disable hook. If that sequence is too</span></span><br><span class="line"><span class="comment">         * simple drivers can just add their own hooks and call it from this</span></span><br><span class="line"><span class="comment">         * CRTC callback here by looping over all encoders connected to it using</span></span><br><span class="line"><span class="comment">         * for_each_encoder_on_crtc().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is used both by legacy CRTC helpers and atomic helpers.</span></span><br><span class="line"><span class="comment">         * Atomic drivers don&#x27;t need to implement it if there&#x27;s no need to</span></span><br><span class="line"><span class="comment">         * disable anything at the CRTC level. To ensure that runtime PM</span></span><br><span class="line"><span class="comment">         * handling (using either DPMS or the new &quot;ACTIVE&quot; property) works</span></span><br><span class="line"><span class="comment">         * @disable must be the inverse of @atomic_enable for atomic drivers.</span></span><br><span class="line"><span class="comment">         * Atomic drivers should consider to use @atomic_disable instead of</span></span><br><span class="line"><span class="comment">         * this one.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * With legacy CRTC helpers there&#x27;s a big semantic difference between</span></span><br><span class="line"><span class="comment">         * @disable and other hooks (like @prepare or @dpms) used to shut down a</span></span><br><span class="line"><span class="comment">         * CRTC: @disable is only called when also logically disabling the</span></span><br><span class="line"><span class="comment">         * display pipeline and needs to release any resources acquired in</span></span><br><span class="line"><span class="comment">         * @mode_set (like shared PLLs, or again release pinned framebuffers).</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Therefore @disable must be the inverse of @mode_set plus @commit for</span></span><br><span class="line"><span class="comment">         * drivers still using legacy CRTC helpers, which is different from the</span></span><br><span class="line"><span class="comment">         * rules under atomic.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*disable)(<span class="keyword">struct</span> drm_crtc *crtc);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_check:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers should check plane-update related CRTC constraints in this</span></span><br><span class="line"><span class="comment">         * hook. They can also check mode related limitations but need to be</span></span><br><span class="line"><span class="comment">         * aware of the calling order, since this hook is used by</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_planes() whereas the preparations needed to</span></span><br><span class="line"><span class="comment">         * check output routing and the display mode is done in</span></span><br><span class="line"><span class="comment">         * drm_atomic_helper_check_modeset(). Therefore drivers that want to</span></span><br><span class="line"><span class="comment">         * check output routing and display mode constraints in this callback</span></span><br><span class="line"><span class="comment">         * must ensure that drm_atomic_helper_check_modeset() has been called</span></span><br><span class="line"><span class="comment">         * beforehand. This is calling order used by the default helper</span></span><br><span class="line"><span class="comment">         * implementation in drm_atomic_helper_check().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * When using drm_atomic_helper_check_planes() this hook is called</span></span><br><span class="line"><span class="comment">         * after the &amp;drm_plane_helper_funcs.atomic_check hook for planes, which</span></span><br><span class="line"><span class="comment">         * allows drivers to assign shared resources requested by planes in this</span></span><br><span class="line"><span class="comment">         * callback here. For more complicated dependencies the driver can call</span></span><br><span class="line"><span class="comment">         * the provided check helpers multiple times until the computed state</span></span><br><span class="line"><span class="comment">         * has a final configuration and everything has been checked.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is also allowed to inspect any other object&#x27;s state and</span></span><br><span class="line"><span class="comment">         * can add more state objects to the atomic commit if needed. Care must</span></span><br><span class="line"><span class="comment">         * be taken though to ensure that state check and compute functions for</span></span><br><span class="line"><span class="comment">         * these added states are all called, and derived state in other objects</span></span><br><span class="line"><span class="comment">         * all updated. Again the recommendation is to just call check helpers</span></span><br><span class="line"><span class="comment">         * until a maximal configuration is reached.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the atomic modeset helpers and by the</span></span><br><span class="line"><span class="comment">         * transitional plane helpers, but it is optional.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">NOTE:</span></span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is called in the check phase of an atomic update. The</span></span><br><span class="line"><span class="comment">         * driver is not allowed to change anything outside of the free-standing</span></span><br><span class="line"><span class="comment">         * state object passed-in.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Also beware that userspace can request its own custom modes, neither</span></span><br><span class="line"><span class="comment">         * core nor helpers filter modes to the list of probe modes reported by</span></span><br><span class="line"><span class="comment">         * the GETCONNECTOR IOCTL and stored in &amp;drm_connector.modes. To ensure</span></span><br><span class="line"><span class="comment">         * that modes are filtered consistently put any CRTC constraints and</span></span><br><span class="line"><span class="comment">         * limits checks into @mode_valid.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * RETURNS:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * 0 on success, -EINVAL if the state or the transition can&#x27;t be</span></span><br><span class="line"><span class="comment">         * supported, -ENOMEM on memory allocation failure and -EDEADLK if an</span></span><br><span class="line"><span class="comment">         * attempt to obtain another state object ran into a &amp;drm_modeset_lock</span></span><br><span class="line"><span class="comment">         * deadlock.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> (*<span class="type">atomic_check</span>)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                            <span class="keyword">struct</span> drm_atomic_state *state);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_begin:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers should prepare for an atomic update of multiple planes on</span></span><br><span class="line"><span class="comment">         * a CRTC in this hook. Depending upon hardware this might be vblank</span></span><br><span class="line"><span class="comment">         * evasion, blocking updates by setting bits or doing preparatory work</span></span><br><span class="line"><span class="comment">         * for e.g. manual update display.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is called before any plane commit functions are called.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that the power state of the display pipe when this function is</span></span><br><span class="line"><span class="comment">         * called depends upon the exact helpers and calling sequence the driver</span></span><br><span class="line"><span class="comment">         * has picked. See drm_atomic_helper_commit_planes() for a discussion of</span></span><br><span class="line"><span class="comment">         * the tradeoffs and variants of plane commit helpers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the atomic modeset helpers and by the</span></span><br><span class="line"><span class="comment">         * transitional plane helpers, but it is optional.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*<span class="type">atomic_begin</span>)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                             <span class="keyword">struct</span> drm_atomic_state *state);</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_flush:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Drivers should finalize an atomic update of multiple planes on</span></span><br><span class="line"><span class="comment">         * a CRTC in this hook. Depending upon hardware this might include</span></span><br><span class="line"><span class="comment">         * checking that vblank evasion was successful, unblocking updates by</span></span><br><span class="line"><span class="comment">         * setting bits or setting the GO bit to flush out all updates.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Simple hardware or hardware with special requirements can commit and</span></span><br><span class="line"><span class="comment">         * flush out all updates for all planes from this hook and forgo all the</span></span><br><span class="line"><span class="comment">         * other commit hooks for plane updates.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is called after any plane commit functions are called.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Note that the power state of the display pipe when this function is</span></span><br><span class="line"><span class="comment">         * called depends upon the exact helpers and calling sequence the driver</span></span><br><span class="line"><span class="comment">         * has picked. See drm_atomic_helper_commit_planes() for a discussion of</span></span><br><span class="line"><span class="comment">         * the tradeoffs and variants of plane commit helpers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback is used by the atomic modeset helpers and by the</span></span><br><span class="line"><span class="comment">         * transitional plane helpers, but it is optional.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*<span class="type">atomic_flush</span>)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                             <span class="keyword">struct</span> drm_atomic_state *state);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_enable:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback should be used to enable the CRTC. With the atomic</span></span><br><span class="line"><span class="comment">         * drivers it is called before all encoders connected to this CRTC are</span></span><br><span class="line"><span class="comment">         * enabled through the encoder&#x27;s own &amp;drm_encoder_helper_funcs.enable</span></span><br><span class="line"><span class="comment">         * hook.  If that sequence is too simple drivers can just add their own</span></span><br><span class="line"><span class="comment">         * hooks and call it from this CRTC callback here by looping over all</span></span><br><span class="line"><span class="comment">         * encoders connected to it using for_each_encoder_on_crtc().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is used only by atomic helpers, for symmetry with</span></span><br><span class="line"><span class="comment">         * @atomic_disable. Atomic drivers don&#x27;t need to implement it if there&#x27;s</span></span><br><span class="line"><span class="comment">         * no need to enable anything at the CRTC level. To ensure that runtime</span></span><br><span class="line"><span class="comment">         * PM handling (using either DPMS or the new &quot;ACTIVE&quot; property) works</span></span><br><span class="line"><span class="comment">         * @atomic_enable must be the inverse of @atomic_disable for atomic</span></span><br><span class="line"><span class="comment">         * drivers.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is optional.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*<span class="type">atomic_enable</span>)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                              <span class="keyword">struct</span> drm_atomic_state *state);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @atomic_disable:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This callback should be used to disable the CRTC. With the atomic</span></span><br><span class="line"><span class="comment">         * drivers it is called after all encoders connected to this CRTC have</span></span><br><span class="line"><span class="comment">         * been shut off already using their own</span></span><br><span class="line"><span class="comment">         * &amp;drm_encoder_helper_funcs.disable hook. If that sequence is too</span></span><br><span class="line"><span class="comment">         * simple drivers can just add their own hooks and call it from this</span></span><br><span class="line"><span class="comment">         * CRTC callback here by looping over all encoders connected to it using</span></span><br><span class="line"><span class="comment">         * for_each_encoder_on_crtc().</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This hook is used only by atomic helpers. Atomic drivers don&#x27;t</span></span><br><span class="line"><span class="comment">         * need to implement it if there&#x27;s no need to disable anything at the</span></span><br><span class="line"><span class="comment">         * CRTC level.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * This function is optional.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">void</span> (*atomic_disable)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                               <span class="keyword">struct</span> drm_atomic_state *state);</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * @get_scanout_position:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Called by vblank timestamping code.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns the current display scanout position from a CRTC and an</span></span><br><span class="line"><span class="comment">         * optional accurate ktime_get() timestamp of when the position was</span></span><br><span class="line"><span class="comment">         * measured. Note that this is a helper callback which is only used</span></span><br><span class="line"><span class="comment">         * if a driver uses drm_crtc_vblank_helper_get_vblank_timestamp()</span></span><br><span class="line"><span class="comment">         * for the @drm_crtc_funcs.get_vblank_timestamp callback.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Parameters:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * crtc:</span></span><br><span class="line"><span class="comment">         *     The CRTC.</span></span><br><span class="line"><span class="comment">         * in_vblank_irq:</span></span><br><span class="line"><span class="comment">         *     True when called from drm_crtc_handle_vblank(). Some drivers</span></span><br><span class="line"><span class="comment">         *     need to apply some workarounds for gpu-specific vblank irq</span></span><br><span class="line"><span class="comment">         *     quirks if the flag is set.</span></span><br><span class="line"><span class="comment">         * vpos:</span></span><br><span class="line"><span class="comment">         *     Target location for current vertical scanout position.</span></span><br><span class="line"><span class="comment">         * hpos:</span></span><br><span class="line"><span class="comment">         *     Target location for current horizontal scanout position.</span></span><br><span class="line"><span class="comment">         * stime:</span></span><br><span class="line"><span class="comment">         *     Target location for timestamp taken immediately before</span></span><br><span class="line"><span class="comment">         *     scanout position query. Can be NULL to skip timestamp.</span></span><br><span class="line"><span class="comment">         * etime:</span></span><br><span class="line"><span class="comment">         *     Target location for timestamp taken immediately after</span></span><br><span class="line"><span class="comment">         *     scanout position query. Can be NULL to skip timestamp.</span></span><br><span class="line"><span class="comment">         * mode:</span></span><br><span class="line"><span class="comment">         *     Current display timings.</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns vpos as a positive number while in active scanout area.</span></span><br><span class="line"><span class="comment">         * Returns vpos as a negative number inside vblank, counting the number</span></span><br><span class="line"><span class="comment">         * of scanlines to go until end of vblank, e.g., -1 means &quot;one scanline</span></span><br><span class="line"><span class="comment">         * until start of active scanout / end of vblank.&quot;</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * Returns:</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * True on success, false if a reliable scanout position counter could</span></span><br><span class="line"><span class="comment">         * not be read out.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">bool</span> (*get_scanout_position)(<span class="keyword">struct</span> drm_crtc *crtc,</span><br><span class="line">                                     <span class="type">bool</span> in_vblank_irq, <span class="type">int</span> *vpos, <span class="type">int</span> *hpos,</span><br><span class="line">                                     <span class="type">ktime_t</span> *stime, <span class="type">ktime_t</span> *etime,</span><br><span class="line">                                     <span class="type">const</span> <span class="keyword">struct</span> drm_display_mode *mode);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>



<h3 id="三、CRTC核心API"><a href="#三、CRTC核心API" class="headerlink" title="三、CRTC核心API"></a>三、CRTC核心API</h3><p><strong>参考文章</strong></p>
<p><strong>[1] <a target="_blank" rel="noopener" href="https://blog.csdn.net/hexiaolong2009/category_9281458.html">DRM (Direct Rendering Manager)</a></strong></p>
<p><strong>[2] Wiki: <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Direct_Rendering_Manager">Direct Rendering Manager</a></strong></p>
<p><strong>[3] <a target="_blank" rel="noopener" href="http://www.wowotech.net/linux_kenrel/dri_overview.html">Linux graphic subsystem(2)_DRI介绍</a></strong></p>
<p><strong>[4] <a target="_blank" rel="noopener" href="https://events.static.linuxfound.org/sites/events/files/slides/brezillon-drm-kms.pdf">The DRM&#x2F;KMS subsystem from a newbie’s point of view</a></strong></p>
<p><strong>[5] <a target="_blank" rel="noopener" href="https://www.cnblogs.com/shoemaker/p/linux_graphics01.html">Linux环境下的图形系统和AMD R600显卡编程(1)</a></strong></p>
<p><strong>[6] <a target="_blank" rel="noopener" href="https://blog.csdn.net/dearsq/article/details/78394388">Linux DRM（二）基本概念和特性</a></strong></p>
<p><strong>[7] <a target="_blank" rel="noopener" href="https://events.static.linuxfound.org/sites/events/files/slides/brezillon-drm-kms.pdf">The DRM&#x2F;KMS subsystem from a newbie’s point of view</a></strong></p>
<p><strong>[8] <a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_41709234/article/details/129472180">DRM驱动概念、组成、框架、源码分析</a></strong></p>
<p><strong>[9] <a target="_blank" rel="noopener" href="https://blog.csdn.net/zichuanning520/article/details/127047436">linux驱动系列学习之DRM（十）</a></strong></p>
<p><strong>[10] <a target="_blank" rel="noopener" href="https://blog.csdn.net/hexiaolong2009/article/details/89810355">DRM 驱动程序开发（开篇）</a></strong></p>
<p><strong>[11] <a target="_blank" rel="noopener" href="https://blog.csdn.net/hexiaolong2009/article/details/105180621">DRM 驱动程序开发（VKMS）</a></strong></p>
<p><strong>[12] <a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/92682047">MIPI自学笔记</a></strong></p>

        
      </div>

         
    </div>
    
     
  </div>
  
    
<nav id="article-nav">
  <a class="article-nav-btn left "
    
      href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20framebuffer/"
      title=""
     >
    <i class="fa-solid fa-angle-left"></i>
    <p class="title-text">
      
        (No Title)
        
    </p>
  </a>
  <a class="article-nav-btn right "
    
      href="/blog/2023/09/11/rk3399/Rockchip%20RK3399%20-%20DRM%20connector/"
      title=""
     >

    <p class="title-text">
      
        (No Title)
        
    </p>
    <i class="fa-solid fa-angle-right"></i>
  </a>
</nav>


  
</article>

 
    </div>
    <div id="footer-wrapper">
      <footer id="footer">
  
  <div id="footer-info" class="inner">
    
    &copy; 2023 Your Name<br>
    Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> & Theme <a target="_blank" rel="noopener" href="https://github.com/saicaca/hexo-theme-vivia">Vivia</a>
  </div>
</footer>

    </div>
    <div class="back-to-top-wrapper">
    <button id="back-to-top-btn" class="back-to-top-btn hide" onclick="topFunction()">
        <i class="fa-solid fa-angle-up"></i>
    </button>
</div>

<script>
    function topFunction() {
        window.scroll({ top: 0, behavior: 'smooth' });
    }
    let btn = document.getElementById('back-to-top-btn');
    function scrollFunction() {
        if (document.body.scrollTop > 600 || document.documentElement.scrollTop > 600) {
            btn.classList.remove('hide')
        } else {
            btn.classList.add('hide')
        }
    }
    window.onscroll = function() {
        scrollFunction();
    }
</script>

  </div>
  <script src="/blog/js/light-dark-switch.js"></script>
</body>
</html>
